【D言語】std.typecons.Tupleを使う

今回は、std.typecons.Tupleとその用途を解説していきます。

Tupleの解説

Tupleとは、他の言語にあるものと同様、様々な型をまとめる型です。 無名構造体のようなものです。 D言語では、Tupleは言語仕様ではなくライブラリとして実装しています。

作り方

以下のように作ります。


import std.typecons;
void main(){
    Tuple!(int, string) t; // intとstringのTuple
    auto t2 = tuple(6, "6", [0, 1, 2]); // tupleという関数を使ってTupleを作成。生成されたTupleはTuple!(int, string, int[3])型
    auto t3 = Tuple!(int, string)(6, "12"); // 構造体リテラルを使ってTupleを作成
}

使い方

以下のように使います。


import std.typecons, std.stdio;
void main(){
    auto t = tuple(6, "Hello, world!");
    t[0].writeln(); // 6
    t[1].writeln(); // Hello, world!
    t[0] += 30;
    t[1] ~= "?";
    t[0].writeln(); // 36
    t[1].writeln(); // Hello, world!?
}

Tupleは、配列のようにアクセスします。 ただし、インデックス部分にはコンパイル時に決定可能な定数しか指定できません。変数は無理です。 そんな訳で、以下のコードはコンパイルが通りません。


import std.typecons, std.stdio;
void main(){
    auto t = tuple(6, "12", 18);
    for(int i = 0; i < t.length; ++i){
        t[i].writeln();
    }
}

上のコードが意図したことは、foreach文を使うことによって実現できます。


import std.typecons, std.stdio;
void main(){
    auto t = tuple(6, "12", 18);
    foreach(e; t){
        e.writeln();
    }
}

構造体的な使い方

Tupleの要素に名前をつけることができます。


import std.typecons, std.stdio;
void main(){
    auto pos = Tuple!(int, "x", int, "y")(30, 40);
    pos.x += 10; // pos[0] += 10; と同じ
    pos.y += 10; // pos[1] += 10; と同じ
    pos.x.writeln(); // 40
    pos.y.writeln(); // 50
}

要素に名前をつけることによって、完全にTupleを無名構造体のように使うことができます。

用途

関数から複数の値を返したい時に、Tupleが使えます。


import std.typecons, std.stdio;
struct Sprite{
    int x, y;
    Tuple!(int, "x", int "y") point(){
        return typeof(return)(x, y); // typeof(return) で関数の戻り値の方を取得できる
    }
}
void main(){
    auto sp = Sprite(10, 20);
    auto point = sp.point();
    point.x.writeln(); // 10
    point.y.writeln(); // 20
}

まとめ

Tupleを使うと、複数の値を返したい時にわざわざ構造体を作る必要がなくなり、とても便利です。 みなさんも、ぜひ使ってみてください。