私は次のコードでいくつかの思考の問題を抱えています
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
ご覧のとおり、コードは私が作成しているワーカーではなく、そのコピーを返しています。実際の労働者を返すにはどうすればよいですか? *と&のいくつかのバリエーションをさまざまなワーカーで試しましたが、次のいずれかになります。
invalid indirect of worker literal (type worker)
または:
cannot use wrk (type worker) as type *worker in return argument
これを行う方法に関するアイデアはありますか?
_func (cmp *Company) NewWorker(name string) *worker {
wrk := worker{Name: name}
cmp.Workers = append(cmp.Workers, wrk)
return &wrk
}
_
_&
_は常に「アドレスを取る」を意味します(バイナリビット演算子バージョンを除く)。 _*
_は、コンテキストによって意味が変わります。式_*Type
_は、「タイプへのポインター」を意味します。表現_*Pointer
_は、「ポインターが指すオブジェクト」を意味します。 _invalid indirect of worker literal
_という式を使用しようとすると、_*wrk
_が返されるのはこのためです。「wrk
が指すオブジェクトを教えて」と言っているのに、wrk
がポインターではないためです。
そのため、戻り値の型として_*worker
_(ワーカーへのポインターを返す)が必要であり、返す構造体のアドレスである_&wrk
_を返します。
もう1つの方法は、組み込みの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
}
_
とはいえ、ここでワーカー構造へのポインターを返す理由はほとんどありません。構造体自体には2つのフィールドしかなく、どちらも既に参照型です(文字列は基本的に不変のスライスです)。したがって、構造体全体の長さは5マシンワード(20ビットまたは40バイト、32ビットか32ビットか)によって異なります。 64ビット)。戻り後に構造体を変更するのではなく、Company構造体に格納するバージョンもコピーです(Companyは、ワーカーへのポインターのスライスではなく、ワーカーのスライスを保持します)。