type Friend struct {
name string
age int
}
type Friends struct {
friends []Friend
}
我想打Friends
范围,能,这意味着,如果我有一个变量my_friends
与Friends
类型,我可以循环使用虽:使结构“范围”?
for i, friend := range my_friends {
// bla bla
}
是可以进去吗?
type Friend struct {
name string
age int
}
type Friends struct {
friends []Friend
}
我想打Friends
范围,能,这意味着,如果我有一个变量my_friends
与Friends
类型,我可以循环使用虽:使结构“范围”?
for i, friend := range my_friends {
// bla bla
}
是可以进去吗?
例如,
var my_friends Friends
for i, friend := range my_friends.friends {
// bla bla
}
这不是真正的原始问题的答案。 – simonmenke
@simonmenke是的,但它可以更清楚地表明OP不需要什么。 –
当心:作为deft_code提到,此代码泄漏的信道和一个的goroutine当循环中断。不要将其用作一般模式。
在走,没有办法作出range
兼容任意类型, range
只支持切片,数组,渠道和地图。
您可以使用range
来迭代通道,如果您想迭代动态生成的数据而无需使用片或数组,那么这非常有用。
例如:
func Iter() chan *Friend {
c := make(chan *Friend)
go func() {
for i:=0; i < 10; i++ {
c <- newFriend()
}
close(c)
}()
return c
}
func main() {
// Iterate
for friend := range Iter() {
fmt.Println("A friend:", friend)
}
}
这就是你可以做一些 'rangeable' 最接近。
因此,通常的做法是在您的类型上定义方法Iter()
或类似的东西, 将其传递给range
。
请参阅the spec以进一步阅读range
。
当然不利的一面是,与跨越切片相比,在这里使用频道效率不高。每个通道的读/写都可能导致运行时切换到不同的goroutine,在大多数情况下,您可以在一个切片上进行切片而不会被其他goroutine抢占。 –
这是真实的,直到构造切片是昂贵的或其他不合需要的。例如,在[cbfs](https://github.com/couchbaselabs/cbfs)中,我有时会遍历所有文件(或范围内的文件)。可能有数十亿个,它需要对数据库的批量请求和有趣的东西。 – Dustin
如果范围没有迭代到完成,这会泄漏通道和goroutine。泄漏的简单解决方案导致比赛或死锁。完整的强大解决方案非常复杂和微妙。 Google内部Go邮件列表的共识是这是一个反模式。 –
有好友要成为一个结构?否则简单地做
type Friends []Friend
我认为这是一个非常好的答案。如果“朋友结构”只包含显示的内容,则将该类型定义为“类型Friends []朋友”。 Go可以使用这种类型的方法,而不仅仅是'struct's,它与大多数语言有点不同。 –
这是一个很好的答案,只要你不需要一个结构... –
你能说出一个真实世界的用例吗?即,为什么你想要这个,而不是'范围Friends.friends'或'范围Friends.List()'(仅限示例)? –
示例:稍后将列表升级到家庭列表(朋友组),并且您不希望更改现有的客户端代码,这些代码完全适用于单个朋友。 – Stein