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