157

Tour of Goの最後の演習を行っているときに、( stringint)ペアのキューが必要であると判断しました。それはとても簡単です:

type job struct {
    url string
    depth int
}

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

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

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

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

動作しませんでした。

4

4 に答える 4

112

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

編集:ニックの提案に従って、スニペットを完全な実例に置き換えました。遊び場のリンク: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}
}

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

于 2012-12-02T16:06:06.363 に答える
77

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

Nickの答えは、を使用して任意のタイプを処理する同様のことを行う方法を示していますinterface{}。(構造体ではなく配列を使用してタプルのようにインデックスを作成できるようにしたかもしれませんが、重要なアイデアはinterface{}型です)

私の他の答えは、匿名の構造体を使用して型を作成することを回避する同様のことを行う方法を示しています。

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

于 2012-12-03T15:08:35.400 に答える
53

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

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

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

于 2012-12-02T16:15:23.960 に答える
3

Go 1.18(2022年2月にリリースされると推定)は、ジェネリックのサポートを追加します。

これにより、タプルタイプの宣言が非常に簡単になります。

type Pair[T, U any] struct{
    T First
    U Second
}

func main() {
    queue := make(chan Pair[string, int])
}

今すぐベータ版で試すことができます!

私が書いたような一般的なタプル(go-tuple)用のライブラリを使用することもできます。

于 2021-12-29T09:27:50.030 に答える