2010-06-28 4 views
8

Dies funktioniert nicht in D:Übergeben auto-typisierte Vars, um in D zu funktionieren?

void doSomething(auto a, auto b){ 
    // ... 
} 

Ich bin nur neugierig, wird dies jemals funktionieren? Oder ist das technisch unmöglich? (Oder einfach nur dumm?)

In jedem Fall, kann dies auf andere Weise erreicht werden? Ich nehme an, ich könnte die ... verwenden und durch die Argumentliste schauen, aber ich mache irgendwie eine Bibliothek für faule Anfänger Leute und will, dass sie in der Lage sind, Funktionen leicht zu verursachen, ohne sich wirklich um Datentypen zu kümmern. Ich spiele mit dem Gedanken, eine Struktur var wie

struct var{ 
    byte type; 
    void* data 
    // ... 
} 

// and overload like all operators so that a lazy devver can do 

var doSomething(var a, var b){ 
    if(a == "hello") 
     b = 8; 
    var c = "No.:" ~ b ~ " says:" ~ a; 
    return c; 
} 

genannt Schaffung Aber mein Kopf beginnt bereits direkt dort zu verletzen. Und ich fühle irgendwie, dass ich etwas verpasse. Ich bin mir auch schmerzlich bewusst, dass dies wahrscheinlich die Vorlagen für ... Sind sie? Von der kleinen, ich weiß, würde eine Vorlage wie folgt aussehen (?)

void doSomething(T, U)(T a, U b){ 
    // ... 
} 

Aber jetzt sieht es nicht mehr so ​​sauber aus. Vielleicht bekomme ich das alles zurück. Vielleicht beruht meine Verwirrung auf meiner Überzeugung, dass auto ein dynamischer Typ ist, vergleichbar mit var ich Javascript, aber wenn in Wirklichkeit ist es etwas anderes?

Und wenn es kein dynamischer Typ ist, und dies ist wahrscheinlich ein ganz anderes Thema, ist es möglich, einen zu erstellen? Oder ist vielleicht sogar eine Open-Source-Lib verfügbar? Eine Liblazy vielleicht?

(. PS Ja, vielleicht der faule devver ist mir:)

+0

Danke allen! Wusste nicht über Variante! Ok, ich verstehe Variante ist ein bisschen "Offroad" für D. – 0scar

Antwort

6

Ich füge einfach hinzu, dass etwas in der Nähe Ihrer Idee von Laufzeittyp Polymorphismus (die var Struktur) bereits im std.variant Modul (nur D2) implementiert ist.

Außerdem ist technisch auto wirklich ein Schlüsselwort, das nichts tut - es wird verwendet, wo Sie einen Typenmodifikator ohne einen Typ benötigen. Wenn Sie keinen Typ angeben, leitet D den Initialisierungsausdruck für Sie ab. Zum Beispiel alle diese Arbeiten:

auto i = 5; 
const j = 5; 
static k = 5; 
12

Wenn doSomething über jede Art von a generisch ist und b, dann ist die Template-Version das Richtige zu tun ist:

void doSomething(T, U)(T a, U b) { 
    // etc. 
} 

Der Compiler erkennt die zum Zeitpunkt der Kompilierung von T und U dargestellten Typen und generiert den richtigen Code.

2

Stop, tu das nicht! Ich fürchte, wenn Sie Typen früh ignorieren, wird es schwieriger, sie zu erfassen, besonders da D nicht dynamisch typisiert wird. Ich glaube, dass Typen auch in dynamischen Sprachen wichtig sind.

Sie können den Typ in D2 ignorieren, indem Sie std.variant verwenden und den Code so aussehen lassen, als ob die Sprache dynamisch eingegeben wird.

Sie haben die Verwendung der Vorlage korrekt, aber nicht automatisch. D erlaubt Ihnen die Verwendung dieses Wortes in vielen Fällen, wie zum Beispiel den Rückgabetyp, da D ein sehr gutes System zum Ableiten eines Typs hat. Parameter sind etwas, das nicht mit doppelten Informationen für den Typ, auf den geschlossen werden soll, geliefert wird.

Zusätzliche Informationen zu Std.Variante: Wenn Sie dies genauer betrachten, ist das immer noch komplizierter als das, was Sie wünschen. Um beispielsweise den Wert einer typisierten Variablen zuzuweisen, ist ein Methodenaufruf erforderlich. und Sie können nicht auf Klassenmethoden von der Referenz zugreifen.

int b = a.get!(int); 
a.goFish() // Error Variant type doesn't have goFish method 
1

Maybe my confusion stems from my belief that auto is a dynamic type, comparable to var i javascript, but when in reality, it's something else?

auto ist ein storage class. In der Tat ist es die Standardspeicherklasse. es bedeutet nichts weiter als "das hat eine Speicherklasse".

Wenn nun der Compiler den Typ eindeutig ableiten kann, dann ist alles in Ordnung. Ansonsten ist es ein Fehler:

auto i = 42; // An integer literal is inferred to be of type 'int'. 
auto j;  // Error! 

So auto kein Typ überhaupt. Denken Sie daran, dass dies alles zur Kompilierzeit geschehen muss, nicht zur Laufzeit. Lassen Sie uns also an einer Funktion aussehen:

auto add(auto a, auto b) 
{ 
    return a + b; 
} 

Kann der Compiler schließen automatisch die Typen von a, b oder der return Wert? Nee. Zusätzlich zu den Grundelementen, die mit dem add -Operator arbeiten (int, byte, double usw.), könnten benutzerdefinierte Typen die Funktion überladen und so weiter. Da der Compiler keinen dieser Typen eindeutig ableiten kann, handelt es sich um einen Fehler. Typen müssen in Parametern angegeben werden, da sie im Allgemeinen nicht abgeleitet werden können (im Gegensatz zu z. B. Deklarationen).