创建一个可迭代的结构体?

huangapple go评论80阅读模式
英文:

Make a struct "range-able"?

问题

type Friend struct {
name string
age int
}

type Friends struct {
friends []Friend
}

我想让Friends可以进行范围循环,也就是说,如果我有一个类型为Friends的变量my_friends,我可以使用以下方式进行循环:

for i, friend := range my_friends {
    // bla bla
}

在Go语言中是否可能实现这样的功能?

英文:
type Friend struct {
    name string
    age  int
}

type Friends struct {
    friends []Friend
}

I'd like to make Friends range-able, that means, if I have a variable my_friends with type Friends, I can loop though it with:

for i, friend := range my_friends {
    // bla bla
}

is it possible in Go?

答案1

得分: 14

有没有必要将Friends定义为一个结构体?否则可以简单地使用以下代码:

type Friends []Friend
英文:

Has Friends to be a struct? Otherwise simply do

type Friends []Friend

答案2

得分: 13

警告:正如deft_code所提到的,当循环中断时,这段代码会泄漏一个通道和一个goroutine。不要将其用作一般模式。


在Go语言中,没有办法使任意类型兼容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() {
  // 迭代
  for friend := range Iter() {
    fmt.Println("一个朋友:", friend)
  }
}

这是您可以做的最接近使某个东西“可迭代”的方法。

因此,一种常见的做法是在您的类型上定义一个名为Iter()或类似的方法,并将其传递给range

有关range的更多信息,请参阅规范

英文:

Beware: As deft_code mentions, this code leaks a channel and a goroutine when the loop breaks. Do not use this as a general pattern.


In go, there is no way to make an arbitrary type compatible for range, as
range only supports slices, arrays, channels and maps.

You can iterate over channels using range, which is useful if you want to iterate over dynamically generated data without having to use a slice or array.

For example:

func Iter() chan *Friend {
   c := make(chan *Friend)
   go func() {
      for i:=0; i &lt; 10; i++ {
        c &lt;- newFriend()
      }
      close(c)
   }()
   return c
}

func main() {
  // Iterate 
  for friend := range Iter() {
    fmt.Println(&quot;A friend:&quot;, friend)
  }
}

That's the closest thing you can have to make something 'rangeable'.

So a common practice is to define a method Iter() or something similar on your type and
pass it to range.

See the spec for further reading on range.

答案3

得分: -1

例如,

var my_friends Friends

for i, friend := range my_friends.friends {
	// bla bla
}
英文:

For example,

var my_friends Friends

for i, friend := range my_friends.friends {
	// bla bla
}

huangapple
  • 本文由 发表于 2012年10月15日 19:08:26
  • 转载请务必保留本文链接:https://go.coder-hub.com/12894333.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定