我对以下代码存在一些思考问题
package main
import (
"fmt"
)
type Company struct {
Name string
Workers []worker
}
type worker struct {
Name string
Other []int
}
func (cmp *Company) NewWorker(name string) worker {
wrk := worker{Name: name}
cmp.Workers = append(cmp.Workers, wrk)
return wrk
}
func main() {
cmp := Company{}
cmp.Name = "Acme"
wrk := cmp.NewWorker("Bugs")
for i := 1; i <= 10; i++ {
wrk.Other = append(wrk.Other, i)
}
fmt.Println(wrk)
fmt.Println(cmp)
}
https://play.golang.org/p/Bja7u148mg
正如您所看到的,代码不会返回我正在创建的工作者,而是它的副本。我怎样才能让它返回真正的工人?我尝试了*和&amp;的一些变化。关于不同的工人,但我最终得到了:
invalid indirect of worker literal (type worker)
或:
cannot use wrk (type worker) as type *worker in return argument
关于如何做到这一点的任何想法?
答案 0 :(得分:15)
func (cmp *Company) NewWorker(name string) *worker {
wrk := worker{Name: name}
cmp.Workers = append(cmp.Workers, wrk)
return &wrk
}
&
始终意味着&#34;取&#34;的地址(二进制位运算符版本除外)。但是,*
会根据具体情况改变含义。表达式*Type
表示&#34;指向Type&#34;的指针。快递*Pointer
表示&#34;指针指向的对象&#34;。这就是为什么如果您尝试使用invalid indirect of worker literal
表达式,则会得到*wrk
,因为您正在说&#34;给我wrk
指向&#34;的对象。 ,但wrk
不是指针。
因此,您需要*worker
作为返回类型(返回指向工作人员的指针),然后返回&wrk
,即您返回的结构的地址。
另一种方法是使用内置的new()
来创建一个指针:
func (cmp *Company) NewWorker(name string) *worker {
wrk := new(worker)
wrk.Name = name
cmp.Workers = append(cmp.Workers, *wrk)
return wrk // wrk is a pointer here
}
所有这一切,没有什么理由在这里返回指向你的工人结构的指针。结构本身只有两个字段,这两个字段都已经是引用类型(字符串本质上只是不可变的片),所以整个结构只有5个机器字长(所以20或40字节,取决于你是否依赖) 32位或64位)。您在返回后不会修改结构,并且您在公司结构中存储的版本也是一个副本(公司包含一小部分工作人员,而不是指向工作人员的一小部分)。