2017-11-01 3 views

答えて

3

ジョナサンは主に右ですが、Rubyでより詳細なとはいえ、その構成部分にtupleを分割する方法は、実際に存在し、かつ任意の便利な型推論なし:

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"); 
} 

が全く組み込まれてありませんしながらあなたの例のような範囲でこれを行うには、ライブラリに実装することが可能です:

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! dmd 2.076では正常に動作します。 D-langがこの種の機能を持っていれば、競争力のあるプログラマがうまくいくでしょう。とにかくありがとうございました。 – hiropon

2

いいえ、それを行う方法はありません。おそらくあなたはいつか起こるだろう多分

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

のようなものとすることができますが、それは今はできません、このような言語にタプルのサポートを追加する方法についてのオフとトークがありました。あなたは

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最終的にはちょうど構造体である、とあなたは魔法のそれを分割することはできませんような何かを行うことができるように最も近いstd.typecons.Tuple/tupleのようなものを使用したことになりますもう一方の端で外に出る。 result[0]result[1]などのインデックスを使用してメンバーにアクセスしたり、Tupleに名前(例: Tuple!(int, "x", int, "y", string, "str") - 名前でメンバーにアクセスできます。 result.x。したがって、Tuple/tupleは、構造体型を明示的に宣言せずに複数の値を返すことができますが、構造体型を作成していますが、値を簡単に返すことはできますが、もう一方の端に自動的に解凍します。それは私たちが持っていない何らかの種類のコンパイラサポートを必要とします。

しかし、我々は言語で、より良いタプルのサポートを持っていた場合でも、何かのような

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

が働いたように、私はあなたがmap以来、仕事と何をしようとして、具体的範囲を返すことを疑います。したがって、メンバー関数を持つオブジェクトであり、分割するタプルではありません。関数コールの正しいセットで抽出できる値のリストを表現するだけです。また、コンパイル時には値の数がわからないため、コンパイラが範囲プリミティブを十分に理解していると見なしても、コンパイル時にそれが存在することを保証することはできませんあなたが割り当てようとしている変数に入れるのに十分な値。正確にその数の値があります。したがって、そのようなものを作ることは不可能ではありませんが(例えば、範囲に十分な値がない場合、コンパイル時にErrorを投げた場合)、実装されていれば驚くでしょう。 Dは静的型付けされた言語であり、動的にその部分を動的にすることになるので、それが言語になるのはかなり外れてしまうでしょう。 Rubyは動的言語なので、それはまったく違う獣です。

タプルを改善しても、言語が改善され、DIP processを通過し承認される必要があります。そのようなことはまだ起こっていません。

+0

ありがとうジョナサン!私はそれが少し難しいと感じた... – hiropon

関連する問題