Go 中的 Pair/tuple 数据类型

我需要一个(stringint)对的队列,这很简单:

type job struct {
url string
depth int
}


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

Go 中是否有内置的成对/元组数据类型?有一个函数支持 返回多个值,但 AFAICT 产生的多值元组在 Go 的类型系统中不是一流的公民。是这样吗?

至于“ what have you try”部分,显而易见的语法(来自 Python 程序员的 POV)

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

没用。

179434 次浏览

你能做到的。它看起来比元组更冗长,但它是一个很大的改进,因为您可以进行类型检查。

编辑: 按照尼克的建议,用完整的工作示例代替了代码片段

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

匿名结构体和字段对于像这样的快速而肮脏的解决方案来说是很好的。但是,对于除了最简单的情况以外的所有情况,您最好像以前那样定义一个命名结构。

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

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

然而,我认为您已经拥有的是完全惯用的,并且这个结构完美地描述了您的数据,这比使用普通元组有很大的优势。

Go 中没有 tuple 类型,你是对的,函数返回的多个值并不代表第一类物件。

Nick 的回答展示了如何使用 interface{}处理任意类型。(我可能使用了数组而不是结构来使其像元组一样可索引,但关键的想法是 interface{}类型)

我的另一个答案展示了如何进行类似的操作,从而避免使用匿名结构创建类型。

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

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

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

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


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

你现在就可以用测试版试试!

您还可以将库用于类似于我编写的(Go-tuple)的泛型元组。

Go 中没有内置的元组/对。我和你有同样的问题,所以我创建了这个简单的包,所以我不需要在我的每个项目中重新发明轮子:

两人一组