Go中的Pair/tuple数据类型

Fre*_*Foo 96 tuples go

在做Tour of Go最后一次练习时,我决定需要一对(string,int)对的队列.这很容易:

type job struct {
    url string
    depth int
}

queue := make(chan job)
queue <- job{url, depth}
Run Code Online (Sandbox Code Playgroud)

但这让我想到:Go中是否有内置的对/元组数据类型?支持从函数返回多个值,但是AFAICT,生成的多个值元组不是Go类型系统中的一等公民.是这样的吗?

至于"你有什么尝试"部分,明显的语法(来自Python程序员的POV)

queue := make(chan (string, int))
Run Code Online (Sandbox Code Playgroud)

没用.

Son*_*nia 77

你可以这样做.它看起来比一个元组更有罗嗦,但它是一个很大的改进,因为你得到类型检查.

编辑:根据尼克的建议,用完整的工作示例替换了代码段.游乐场链接: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}
}
Run Code Online (Sandbox Code Playgroud)

匿名结构和字段适用于这样的快速和脏的解决方案.对于除了最简单的情况之外的所有情况,您最好像定义一样定义命名结构.

  • 您应该描述如何从匿名结构成员中获取值,因为我不认为这对初学者来说是显而易见的! (9认同)
  • 但是,如果有多个具有相同类型的字段,则不起作用 (6认同)
  • 所以答案是"不,没有元组类型"? (4认同)
  • 您可以在匿名结构中命名字段,您只需要确保这些字段的命名方式与匿名结构定义出现的每个位置相同(在此示例中为 3 次。)如果您可以摆脱匿名字段,则更容易. (2认同)

Son*_*nia 48

Go中没有元组类型,并且您是正确的,函数返回的多个值不代表第一类对象.

Nick的答案显示了如何使用类似的方法来处理任意类型interface{}.(我可能使用数组而不是结构使其像元组一样可转换,但关键的想法是interface{}类型)

我的另一个答案显示了如何做类似的事情,避免使用匿名结构创建类型.

这些技术具有元组的一些属性,但不是,它们不是元组.


小智 33

Go 1.18(预计 2022 年 2 月发布)将添加对泛型的支持。

这将使声明元组类型变得非常容易:

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

func main() {
    queue := make(chan Pair[string, int])
}
Run Code Online (Sandbox Code Playgroud)

您现在就可以尝试使用测试版!

您还可以使用通用元组库,例如我编写的库(go-tuple)。

  • 目前,这是该问题最准确的答案。 (2认同)

Nic*_*ood 28

如果你愿意,你可以做这样的事情

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)
}
Run Code Online (Sandbox Code Playgroud)

但是我认为你已经完全不是惯用语,结构完美地描述了你的数据,这比使用普通元组要大.