繁体   English   中英

在地图中的结构上调用指针方法

[英]Calling a pointer method on a struct in a map

有一个类型Company,它是一个结构,包含Person的地图,它也是所有结构。

type Company struct {
    employees map[int]Person
}

type Person struct {
    [...]
}

在将一些Person分配给employees-map之后,我正试图在每个Person上调用指针方法。

func (company *Company) Populate(names []string) {
    for i := 1; i <= 15; i++ {
        company.employees[i] = Person{names[i - 1], [...]}
        company.employees[i].Initialize()
    }
}

由于go-Compiler抱怨我无法在company.employees [i]上调用指针方法,并且我无法获取company.employees [i]的地址,因此失败了。 但是,将Initialize-method设置为非指针方法并让它返回该人的副本 ,并使用它再次将其分配给地图

company.employees[i] = company.employees[i].Initialize()

工作,没有那么不同。

没有使用指针,这非常困扰我。 Map不是不可变的,并且它们都会被修改,所以在地图中的实体上调用指针方法应该不是问题 - 至少在我脑海中。

如果有人能向我解释我在这里做错了什么 - 或者纠正我的想法 - 我会很高兴。

这里的问题是,为了调用指针方法,需要采用employees[i]的地址。 根据Go规范

操作数必须是可寻址的,即,变量,指针间接或切片索引操作; 或可寻址结构操作数的字段选择器; 或者可寻址数组的数组索引操作。 作为可寻址性要求的例外,x也可以是复合文字。

地图索引操作无法寻址。 这是因为地图实现不需要保证值的地址不会改变。 随着更多数据被添加到地图中,它可能出于效率原因重新定位数据。

那么,你怎么解决它? 如果您有map[int]*Person ,则不需要获取地图中数据的地址,因为地图值已经是地址。

最后一点建议, Person.Initialize()不是非常惯用的Go代码。 如果需要初始化类型,通常使用NewPerson()函数。 NewPerson()函数将返回一个初始化的Person结构或指针。

例如,

package main

import "fmt"

type Person struct {
    Name string
}

func NewPerson(name string) *Person {
    return &Person{Name: name}
}

type Company struct {
    Employees map[int]*Person
}

func (c *Company) Populate(names []string) {
    c.Employees = make(map[int]*Person)
    for i := range names {
        c.Employees[i+1] = NewPerson(names[i])
    }
}

func main() {
    c := Company{}
    c.Populate([]string{"Peter", "Paul"})
    for k, v := range c.Employees {
        fmt.Println(k, *v)
    }
}

输出:

1 {Peter}
2 {Paul}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2025 STACKOOM.COM