类型为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不是不可变的,并且它们都会被修改,所以在地图中的实体上调用指针方法应该不是问题 - 至少在我脑海中。
如果有人能向我解释我在这里做错了什么 - 或者纠正我的想法 - 我会很高兴。
答案 0 :(得分:11)
这里的问题是,为了调用指针方法,需要采用employees[i]
的地址。根据{{3}}:
操作数必须是可寻址的,即,变量,指针间接或切片索引操作;或可寻址结构操作数的字段选择器;或者可寻址数组的数组索引操作。作为可寻址性要求的一个例外,x也可以是复合文字。
地图索引操作无法寻址。这是因为地图实现不需要保证值的地址不会改变。随着更多数据被添加到地图中,它可能出于效率原因重新定位数据。
那么,你怎么解决它?如果您有map[int]*Person
,则无需获取地图中数据的地址,因为地图值已经是地址。
最后一点建议,Person.Initialize()
不是非常惯用的Go代码。如果需要初始化类型,通常使用NewPerson()
函数。 NewPerson()
函数将返回初始化的Person结构或指针。
答案 1 :(得分:0)
例如,
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}