英文:
Golang how to range in pointer array
问题
如果我有一个PersonManager结构体,并且它有一个*[]Person数组。我想遍历这个数组中的每个项。例如:
manager := *PersonManager
for ii := 0; len(*manager.allPersons); ii++{
fmt.Println(manager.allPersons[:ii].name)
}
对于这个例子,manager变量是一个指针,而该变量中的数组也是一个指针。我该如何遍历这些项?
注意:我得到了"cannot slice manager.allPersons (type *[]Person)"的错误提示。
英文:
if I have PersonManager struct and it has *[]Person array. I want to range every item in this array. For example
manager := *PersonManager
for ii := 0; len(*manager.allPersons); ii++{
fmt.Println(manager.allPersons[:ii].name)
}
for this example, manager variable is pointer and array that in this variable is pointer too. How can I range this items?
Not: I m getting cannot slice manager.allPersons (type *[]Person) error
答案1
得分: 12
使用range
关键字。https://github.com/golang/go/wiki/Range
for i, person := range *manager.allPerson {
fmt.Println(person.name)
}
请注意,如果您不使用索引变量i
,编译器会报错。如果您不打算使用它,请用_
替换。
进一步解释一下,您最初的错误是因为您第一次正确地解引用了*[]Person
,但在for
循环内部没有解引用。
fmt.Println(manager.allPersons[:ii].name) // 错误
fmt.Println((*manager.allPersons)[:ii].name) // 正确
另外,由于您的slice
包含Person
结构体的值,如果您在range
表达式中使用可选的第二个值,它将不得不进行复制。因此,保持只使用索引会更高效。
作为建议,不要使用*[]Person
,而是使用[]*Person
,这可能是您本来打算使用的。slice
已经是一个指针值。使用[]*Person
,您不必担心range
表达式会复制整个结构体,因为它只是指向Person
的指针。
实际上,除非您将类型更改为[]*Person
或索引到slice
中,否则无法在range
循环中反映出对slice
的更改,因为结构体值将是一个副本。请参阅https://github.com/golang/go/wiki/Range#gotchas,但请注意,如果该值是指针值,则不会出现此问题。
英文:
Use the range
keyword. https://github.com/golang/go/wiki/Range
for i, person := range *manager.allPerson {
fmt.Println(person.name)
}
Note that the compiler will be angry if you don't use the index var i
. If you don't intend to use it, replace with _
.
To further explain, your original error was due to the fact that you correctly dereferenced your *[]Person
the first time, but not inside the for
loop.
fmt.Println(manager.allPersons[:ii].name) // wrong
fmt.Println((*manager.allPersons)[:ii].name) // right
Also, given that your slice
contains Person
struct values, it will have to copy it if you use the optional second value in the range
expression. Thus, it would be more efficient to keep using just the indexes.
As a suggestion, don't use a *[]Person
, use []*Person
, which is probably what you intended to use anyway. A slice
is already a pointer value. Using []*Person
you don't have to fear a copy by the range
expression because it is simply a pointer to a Person
instead of the entire struct.
In fact, unless you either change the type to []*Person
or index into the slice
you won't be able to have changes reflected in the slice because a struct value will be a copy in the range
loop. See https://github.com/golang/go/wiki/Range#gotchas but be aware that if the value is a pointer value, this isn't an issue.
答案2
得分: 2
我觉得你可能对指针有些混淆。你不需要在任何地方解引用指针。像这样的代码应该可以工作:
for i := 0; i < len(manager); i++ {
fmt.Println(manager[i].Name)
}
在这里运行Go代码:
https://play.golang.org/p/P8wAp4wIGs
英文:
I think you might be mixed up by the pointers. You don't need to dereference your pointer anywhere. Something like this should work:
for i := 0; i < len(manager); i++ {
fmt.Println(manager[i].Name)
}
GoPlay here:
https://play.golang.org/p/P8wAp4wIGs
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论