代码之家  ›  专栏  ›  技术社区  ›  hiropon

有没有办法用Dlang同时分配多个变量?

d
  •  4
  • hiropon  · 技术社区  · 7 年前

    通过使用Ruby,我们可以做到这一点。

    s = "split by space"
    A,B,C = s.split(" ").map(&:to_i)
    

    string s = "split by space";
    int A,B,C = s.split(" ").map!(x => x.to!int);
    
    2 回复  |  直到 4 年前
        1
  •  5
  •   Zombo tliff    4 年前

    乔纳森基本上是对的,但事实上有一种方法可以分裂一个 tuple 进入 它的组成部分,虽然比Ruby更详细,而且没有任何方便的功能

    import std.meta : 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");
    }
    

    虽然没有像您的示例那样的内置方法来实现这一点,但它是 可以在库中实现:

    import std.meta : AliasSeq, 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;
    }
    
        2
  •  5
  •   Jonathan M Davis    7 年前

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

    也许有一天会发生,但现在不可能。最接近的是使用类似 std.typecons.Tuple / tuple 这样你就可以做

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

    或者更有可能

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

    但是 Tuple 它最终只是一个结构,你无法在另一端神奇地将其拆分。您必须通过索引访问其成员,例如 result[0] result[1] 元组 带有名称-例如。 Tuple!(int, "x", int, "y", string, "str") -然后,您可以按名称访问成员-例如。 result.x . 所以 / tuple 允许您返回多个值,而无需为此明确声明结构类型,但它仍在为此创建结构类型,虽然它允许您轻松打包要返回的值,但它不允许您在另一端自动解包。这将需要某种我们没有的编译器支持。

    然而,即使我们在语言中有更好的元组支持

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

    成功了,我怀疑你所做的会成功,因为 map 具体返回一个范围。因此,它是一个具有成员函数的对象,而不是任何类型的要拆分的元组。它恰好代表了一系列可以用正确的函数调用来提取的值。编译时它所具有的值的数量是未知的,因此,即使您假设编译器对范围原语有足够的理解,可以为您从中获得一个列表,它也不能保证在编译时有足够的值放入您试图分配给的变量中,更不用说有足够的值了。因此,虽然这样的工作不是不可能的(例如,如果它抛出一个 Error 在编译时,如果这个范围内没有足够的值),我会惊讶于它是否被实现。D是一种静态类型的语言,这将有效地使它的一部分成为动态的,因此它在语言中是非常不符合特征的。Ruby是一种动态语言,所以它是一种非常不同的语言。

    无论如何,对元组的任何改进都是对语言的改进,必须通过 DIP process 并获得批准,但这种情况还没有发生。