更新Go中的切片迭代错误“不支持索引”

40

我正在尝试迭代切片值并通过索引访问它们以更新一个或多个值,或者通过迭代访问它们。然后我遇到了以下问题。

package main

import "fmt"

type Member struct {
    Name, Surname string
    Age           int
}
type Members []Member

func main() {
    members1 := Members{
        {"Bob", "Doe", 30},
        {"Jack", "Doe", 30},
        {"John", "Doe", 30},
    }
    members1.ModifyName()
    members1.ModifyAllNames1()
    members1.ModifyAllNames2()
    fmt.Println(members1)
}

func (members *Members) ModifyName() {

    *members[0].Name = "-"
}

func (members *Members) ModifyAllNames1() {

    for i := 0; i < len(*members); i++ {
        *members[i].Name = "-"
    }
}

func (members *Members) ModifyAllNames2() {

    for _, m := range *members {
        m.Name = "-"
    }
}   

然后我得到以下错误:

invalid operation: members[0] (type *Members does not support indexing)
invalid operation: members[i] (type *Members does not support indexing)
2个回答

84

*Members 不支持索引,Members 支持。

m := make([]Members, 5)
pm := &m

m[:2]     // good
pm[:2]    // bad
(*pm)[:2] // good

https://go.dev/play/p/CDaBKqB-sqM

package main

import "fmt"

type Member struct {
    Name, Surname string
    Age           int
}
type Members []Member

func main() {
    members1 := Members{
        {"Bob", "Doe", 30},
        {"Jack", "Doe", 30},
        {"John", "Doe", 30},
    }
    members1.ModifyName()
    members1.ModifyAllNames1()
    //members1.ModifyAllNames2()
    fmt.Println(members1)
}

func (members *Members) ModifyName() {
    (*members)[0].Name = "-"
}

func (members *Members) ModifyAllNames1() {
    for i := 0; i < len(*members); i++ {
        (*members)[i].Name = "-"
    }
}

func (members Members) ModifyAllNames2() {
    for i := range members {
        members[i].Name = "-"
    }
}

谢谢,Stephen!我有一个问题。什么时候应该使用()?比如(*members)[0]和(*members)[i]... - user3930912
24
编译器将members[0]解释为(members[0])。因此,它首先获取切片的第一个元素,然后应用指针取消引用。你想要的是先取消引用切片,然后获取元素。这可以通过(members)[0]来完成。它首先将应用于切片,然后进行索引。 - Stephen Weinberg
另一个解决方法是将它们变成非指针方法:func (members Members) ModifyName() { members[0].Name = "-" } - Stephen Weinberg
5
您的第三个函数 ModifyAllNames2() 实际上并没有修改 Name 字段。 - briddums
这个问题已经被解决了。ModifyAllNames2()现在已经测试过了。 - Stephen Weinberg

6
func (members *Members) ModifyName() {
    *members[0].Name = "-"
}

invalid operation: members[0] (type *Members does not support indexing)

问题在于运算符的结合性和/或优先级,尽管我在 Golang 规范中没有找到针对这个特定情况的明确说明。
表达式 *members[0].Name 看起来等同于 *(members[0].Name),因此,为了得到正确的指针引用,你需要显式地在需要被解引用的项周围使用一对括号,即 (*members)[0].Name

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接