【问题标题】:Go update slice iterating error "does not support indexing"去更新切片迭代错误“不支持索引”
【发布时间】:2014-10-07 02:18:03
【问题描述】:

我正在尝试遍历切片值并更新一个或多个值,通过索引访问它或遍历它们。那么我有以下问题。

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)

【问题讨论】:

    标签: go


    【解决方案1】:

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

    m := make([]Members, 5)
    pm := &m
    
    m[:2]     // good
    pm[:2]    // bad
    (*pm)[:2] // good
    

    http://play.golang.org/p/_26TUBHdDm

    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 = "-"
        }
    }
    

    【讨论】:

    • 谢谢,斯蒂芬!我有个问题。我什么时候应该使用()?喜欢 (*members)[0] 和 (*members)[i]...
    • *members[0] 被编译器解释为 *(members[0])。所以首先它获取切片的第一个元素,然后应用指针 deref。你想要的是它首先取消切片,然后获取元素。这可以通过 (*members)[0] 来完成。它首先将 * 应用于切片,然后索引。
    • 另一个答案是让它们不再是指针方法:func (members Members) ModifyName() { members[0].Name = "-" }
    • 您的第三个函数 ModifyAllNames2() 实际上并没有修改 Name 字段
    【解决方案2】:
    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一样。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2022-11-02
      • 2013-12-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多