英文:
Pair/tuple data type in Go
问题
我需要一个(string
, int
)对的队列。这很容易:
type job struct {
url string
depth int
}
queue := make(chan job)
queue <- job{url, depth}
Go语言中有内置的对/元组数据类型吗?虽然函数可以返回多个值,但据我所知,Go语言中产生的多值元组不是一等公民。是这样吗?
至于“你尝试了什么”的部分,显而易见的语法(从Python程序员的角度来看)
queue := make(chan (string, int))
没有起作用。
英文:
I need a queue of (string
, int
) pairs. That's easy enough:
type job struct {
url string
depth int
}
queue := make(chan job)
queue <- job{url, depth}
are there built-in pair/tuple data types in Go? There is support for returning multiple values from a function, but AFAICT, the multiple value tuples produced are not first-class citizens in Go's type system. Is that the case?
As for the "what have you tried" part, the obvious syntax (from a Python programmer's POV)
queue := make(chan (string, int))
didn't work.
答案1
得分: 124
你可以这样做。它看起来比元组更冗长,但它是一个很大的改进,因为你可以进行类型检查。
编辑:根据Nick的建议,用完整的工作示例替换了代码片段。Playground链接: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}
}
匿名结构体和字段对于像这样的快速而简单的解决方案是可以的。但对于除了最简单的情况之外,最好还是像你之前做的那样定义一个命名结构体。
英文:
You can do this. It looks more wordy than a tuple, but it's a big improvement because you get type checking.
Edit: Replaced snippet with complete working example, following Nick's suggestion. Playground link: 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}
}
Anonymous structs and fields are fine for quick and dirty solutions like this. For all but the simplest cases though, you'd do better to define a named struct just like you did.
答案2
得分: 83
在Go语言中没有元组类型,你是正确的,函数返回的多个值并不代表一种一等对象。
Nick的回答展示了如何使用interface{}
处理任意类型的类似操作。(我可能会使用数组而不是结构体,以使其像元组一样可索引,但关键思想是interface{}
类型)
我的另一个回答展示了如何使用匿名结构体来避免创建类型的类似操作。
这些技术具有元组的某些特性,但不,它们不是元组。
英文:
There is no tuple type in Go, and you are correct, the multiple values returned by functions do not represent a first-class object.
Nick's answer shows how you can do something similar that handles arbitrary types using interface{}
. (I might have used an array rather than a struct to make it indexable like a tuple, but the key idea is the interface{}
type)
My other answer shows how you can do something similar that avoids creating a type using anonymous structs.
These techniques have some properties of tuples, but no, they are not tuples.
答案3
得分: 57
你可以像这样做,如果你想的话
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)
// 但是要使用这些值,你需要进行类型断言
s := p1.a.(string) + " now"
fmt.Println("p1.a", s)
}
然而,我认为你已经拥有的代码是完全符合惯用方式的,结构体完美地描述了你的数据,这是使用普通元组所不具备的一个重要优势。
英文:
You could do something like this if you wanted
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)
}
However I think what you have already is perfectly idiomatic and the struct describes your data perfectly which is a big advantage over using plain tuples.
答案4
得分: 28
Go 1.18(预计于2022年2月发布)将添加对泛型的支持。
这将使得声明元组类型非常容易:
type Pair[T, U any] struct {
First T
Second U
}
func main() {
queue := make(chan Pair[string, int])
}
您现在可以尝试使用beta版本!
您还可以使用像我写的一个泛型元组库(go-tuple)来实现。
英文:
Go 1.18 (estimated to be released February 2022) will add support for generics.
This will make it very easy to declare tuple types:
type Pair[T, U any] struct {
First T
Second U
}
func main() {
queue := make(chan Pair[string, int])
}
You can try it with the beta right now!
You can also use a library for generic tuples like the one I wrote (go-tuple).
答案5
得分: 1
在Go语言中没有内置的元组/对。我和你一样遇到了同样的问题,所以我创建了这个简单的包,这样我就不需要在每个项目中重新发明轮子了:
英文:
There are no built-in tuples/pairs in Go. I had the exact same issue with you, so I created this simple package, so I don't need to reinvent the wheel in my every project:
答案6
得分: 0
type Pair struct {
values [2]interface{}
}
func MakePair(k, v interface{}) Pair {
return Pair{values:[2]interface{}{k, v}}
}
func (p Pair) Get(i int) interface{} {
return p.values[i]
}
func main() {
p := MakePair("Hello", false)
fmt.Println(p.Get(0), " ", p.Get(1))
}
英文:
type Pair struct {
values [2]interface{}
}
func MakePair(k, v interface{}) Pair {
return Pair{values:[2]interface{}{k, v}}
}
func (p Pair) Get(i int) interface{} {
return p.values[i]
}
func main() {
p := MakePair("Hello", false)
fmt.Println(p.Get(0), " ", p.Get(1))
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论