I am having some thought issues with the following code
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
As you can see the code is not returning the worker I am creating but a copy of it. How can I get it to return the actual worker? I have tried some variations of * and & on the different workers but I end up with either:
invalid indirect of worker literal (type worker)
or:
cannot use wrk (type worker) as type *worker in return argument
Any ideas on how to do this?
To be specific, Go does not support “Pass-By-Reference” semantic in any way. The reason is simple; Go does not support a reference variable as you have in other programming languages like C++.
One of them asked if you could return a struct from a function, to which I replied: "No! You'd return pointers to dynamically malloc ed struct s instead."
Go struct access fields The struct fields are accessed with the dot operator. We create an empty User struct. We initialize the fields with values and read them using the dot operator.
Pointers in Go programming language or Golang is a variable which is used to store the memory address of another variable. We can pass pointers to the function as well as return pointer from a function in Golang.
func (cmp *Company) NewWorker(name string) *worker {
wrk := worker{Name: name}
cmp.Workers = append(cmp.Workers, wrk)
return &wrk
}
&
always means "take the address of" (except for the binary bitwise operator version). *
, however, changes meaning depending on the context. The expression *Type
means "pointer to Type". The express *Pointer
means "the object that Pointer points to". This is why you get an invalid indirect of worker literal
if you try to use the expression *wrk
, because you're saying "give me the object that wrk
points to", but wrk
isn't a pointer.
As such, you need *worker
as your return type (returning a pointer to a worker), and you return &wrk
, the address of the structure you're returning.
Another alternative is to use the built in new()
to create a pointer in the first place:
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
}
All that said, there's little reason to return a pointer to your worker structure here. The structure itself only has two fields, both of which are already reference types (strings are essentially just immutable slices), so the entire structure is only 5 machine words long (so 20 or 40 bytes, depending on whether you're on 32bit or 64bit). You're not modifying the struct after return, and the version you store in the Company struct is also a copy (Company holds a slice of workers, not a slice of pointers to workers).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With