2017-11-01 7 views

Antwort

3

Jonathan ist meistens richtig, aber es gibt in der Tat eine Möglichkeit, eine tuple in seine Bestandteile aufzuspalten, wenn auch ausführlicher als in Ruby und ohne handliche Typinferenz:

import std.traits : AliasSeq; 
import std.typecons : tuple; 

auto foo() { return tuple(42, 29, "hello"); } 

unittest { 
    int a, b; 
    string c; 
    AliasSeq!(a, b, c) = foo(); // Look ma, magic! 
    assert(a == 42); 
    assert(b == 29); 
    assert(c == "hello"); 
} 

Obwohl es keine gibt es gebaut -In Möglichkeit, dies mit Bereichen wie Ihr Beispiel zu tun, ist es möglich, in einer Bibliothek zu implementieren:

import std.traits : AliasSeq; 
import std.meta : Repeat; 
import std.typecons : Tuple, tuple; 
import std.algorithm : map; 
import std.conv : to; 
import std.string : split; 
import std.range : isInputRange, ElementType; 

unittest { 
    string s = "1 2 3"; 
    int A,B,C; 
    AliasSeq!(A,B,C) = s.split(" ").map!(x => x.to!int).tuplify!3; 
    assert(A == 1); 
    assert(B == 2); 
    assert(C == 3); 
} 

auto tuplify(size_t n, R)(R r) if (isInputRange!R) { 
    Tuple!(Repeat!(n, ElementType!R)) result; 

    static foreach (i; 0..n) { 
     result[i] = r.front; 
     r.popFront(); 
    } 
    assert(r.empty); 

    return result; 
} 
+0

Splendid! Es funktioniert gut auf dmd 2.076. Wenn D-lang diese Art von Funktion hätte, wäre der kompetitive Programmierer glücklich. Trotzdem danke. – hiropon

2

Nein, es gibt keine Möglichkeit, das zu tun. Es war die Rede off-und-on über möglicherweise Tupel Unterstützung der Sprache Hinzufügen, so dass Sie könnte so etwas wie

int a; 
int b; 
string c; 
(a, b, c) = foo(); 

und vielleicht, dass eines Tages passieren wird, aber es ist nicht möglich, gerade jetzt. Die nächstgelegene würde mit so etwas wie std.typecons.Tuple/tuple, so dass Sie so etwas wie

Tuple!(int, int, string) foo() { return tuple(42, 29, "hello"); } 
Tuple!(int, int, string) result = foo(); 

oder eher

auto foo() { return tuple(42, 29, "hello"); } 
auto result = foo(); 

aber Tuple ist letztlich nur eine Struktur tun, und Sie können nicht auf magische Weise spaltete am anderen Ende. Sie müssen auf seine Mitglieder über Indizes wie result[0] oder result[1] zugreifen, oder wenn Sie Tuple mit Namen deklarieren - z. Tuple!(int, "x", int, "y", string, "str") - dann können Sie auf die Mitglieder mit Namen zugreifen - z.B. result.x. So können Sie mit Tuple/tuple mehrere Werte zurückgeben, ohne explizit einen Struct-Typ zu deklarieren, aber dafür wird immer noch ein Strukturtyp erstellt Entpacken Sie sie automatisch am anderen Ende. Das würde Compiler-Unterstützung irgendeiner Art erfordern, die wir nicht haben.

Aber auch wenn wir in der Sprache so besser Tupel Unterstützung hatten, dass so etwas wie

(a, b, c) = foo(); 

gearbeitet, ich bezweifle, dass das, was Sie versuchen, funktionieren würde, zu tun, da map speziell einen Bereich zurückkehrt. Also, es ist ein Objekt mit Member-Funktionen, kein Tupel irgendeiner Art, das aufgeteilt werden soll. Es stellt lediglich eine Liste von Werten dar, die mit den richtigen Funktionsaufrufen extrahiert werden können. Und die Anzahl der Werte, die es hat, ist zur Kompilierungszeit nicht bekannt. Selbst wenn Sie annehmen, dass der Compiler die Bereichsgrundelemente gut genug versteht, um eine Liste von ihnen für Sie zu erhalten, kann es zur Kompilierungszeit nicht garantieren, dass es solche gibt Genügend Werte, die Sie in die Variablen eingeben können, die Sie zuweisen möchten, ganz zu schweigen davon, dass genau diese Anzahl von Werten vorhanden ist. Also, obwohl es nicht unmöglich wäre, so etwas zu machen (z. B. wenn es eine Error zur Kompilierzeit warf, wenn es nicht genügend Werte in dem Bereich gab), wäre ich überrascht, wenn das implementiert wäre. D ist eine statisch typisierte Sprache, die ein Stück davon dynamisch machen würde, so dass es ziemlich untypisch wäre, wenn es in der Sprache wäre. Ruby ist eine dynamische Sprache, also ist es ein ganz anderes Biest.

Unabhängig davon, jede Verbesserung mit Tupeln wäre Verbesserungen an der Sprache und würde durch die DIP process gehen und genehmigt werden, und nichts dergleichen ist noch passiert.

+0

Danke Jonathan! Ich fühlte, dass es ein bisschen schwierig ist ... – hiropon

Verwandte Themen