返回Go-lang中struct的引用

时间:2016-08-25 14:02:57

标签: pointers go struct

我对以下代码存在一些思考问题

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

关于如何做到这一点的任何想法?

1 个答案:

答案 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位)。您在返回后不会修改结构,并且您在公司结构中存储的版本也是一个副本(公司包含一小部分工作人员,而不是指向工作人员的一小部分)。