Goのペア/タプルデータ型


118

Tour of Go最後の練習をしているときに、(stringint)ペアのキューが必要だと判断しました。とても簡単です。

type job struct {
    url string
    depth int
}

queue := make(chan job)
queue <- job{url, depth}

しかし、これは私に考えさせました:Goに組み込みのペア/タプルデータ型はありますか?関数から複数の値返すことがサポートされていますが、生成された複数の値のタプルは、Goの型システムでは一流の市民ではありません。それは事実ですか?

「何を試しましたか」の部分については、明白な構文(PythonプログラマーのPOVから)

queue := make(chan (string, int))

うまくいきませんでした。

回答:


57

Goにはタプルタイプはありません。正しいのですが、関数によって返される複数の値は、ファーストクラスのオブジェクトを表していません。

Nickの答えは、を使用して任意の型を処理する同様の方法をどのように実行できるかを示していますinterface{}。(タプルのようにインデックス可能にするために、構造体ではなく配列を使用した可能性がありますが、重要なアイデアはinterface{}型です)

私の他の答えは、匿名の構造体を使用して型を作成しないようにする方法を示しています。

これらの手法にはタプルのいくつかの特性がありますが、タプルではありません。


91

あなたはこれを行うことができます。タプルよりも単語のように見えますが、型チェックができるため、大幅に改善されています。

編集:Nickの提案に従って、スニペットを完全に機能する例に置き換えました。プレイグラウンドリンク:http : //play.golang.org/p/RNx_otTFpk

package main

import "fmt"

func main() {
    queue := make(chan struct {string; int})
    go sendPair(queue)
    pair := <-queue
    fmt.Println(pair.string, pair.int)
}

func sendPair(queue chan struct {string; int}) {
    queue <- struct {string; int}{"http:...", 3}
}

匿名の構造体とフィールドは、このような迅速で汚いソリューションには問題ありません。ただし、最も単純な場合を除いて、名前付き構造体を定義した方がよいでしょう。


9
初心者には明らかではないので、匿名の構造体メンバーから値を取得する方法を説明する必要があります。
Nick Craig-Wood

9
ただし、同じタイプのフィールドが複数ある場合、これは機能しません
newacct

1
匿名構造体に名前付きフィールドを含めることができます。匿名構造体定義が表示されるそれぞれの場所に同じ名前が付けられていることを確認する必要があります(この例では3回です)。 。
ソニア

5
それで答えは「いいえ、タプルタイプはありません」ですか?
Fred Foo

37

あなたが望むならあなたはこのようなことをすることができます

package main

import "fmt"

type Pair struct {
    a, b interface{}
}

func main() {
    p1 := Pair{"finished", 42}
    p2 := Pair{6.1, "hello"}
    fmt.Println("p1=", p1, "p2=", p2)
    fmt.Println("p1.b", p1.b)
    // But to use the values you'll need a type assertion
    s := p1.a.(string) + " now"
    fmt.Println("p1.a", s)
}

しかし、私はあなたがすでに持っているものは完全に慣用的であり、構造体はデータを完全に記述していると思います。これはプレーンタプルを使用するよりも大きな利点です。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.