The code below returns the error multiple-value in single-value context
. I fail to understand why because it can't be more clear that the function has one argument ( I pass an empty string ""), and returns a string and an error (I assign it to r
and err
).
package main
import "fmt"
type Some struct{}
func main() {
cl := Some{}
r, err := &cl.Start("")
fmt.Println(r)
}
func (cs *Some) Start(sg string) (string, error) {
return sg, nil
}
It's an operator precedence thing. &cl.Start()
is the same as &(cl.Start())
, which isn't what you want.
Use parentheses to clarify that what you want is (&cl).Start()
.
Or you could just use a pointer variable.
func main() {
cl := &Some{}
r, err := cl.Start("")
fmt.Println(r)
}
As already stated in the comment, remove the & from &cl.Start("") and it will work - though you'l then get an error about err being declared and not used.
Or you can write it as (&cl).Start("")
and that too will work.
The explanation is here:
The rule about pointers vs. values for receivers is that value methods can be invoked on pointers and values, but pointer methods can only be invoked on pointers.
This rule arises because pointer methods can modify the receiver; invoking them on a value would cause the method to receive a copy of the value, so any modifications would be discarded. The language therefore disallows this mistake. There is a handy exception, though. When the value is addressable, the language takes care of the common case of invoking a pointer method on a value by inserting the address operator automatically.
and also here:
A method call x.m() is valid if the method set of (the type of) x contains m and the argument list can be assigned to the parameter list of m. If x is addressable and &x's method set contains m, x.m() is shorthand for (&x).m()