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()
Related
I started learning golang a couple of days ago and found reflect.Valueof() and Value.Elem() quite confusing. What is the difference between this two function/methods and how to use them correctly?
Both function/methods return a Value, and according to the go doc
ValueOf returns a new Value initialized to the concrete value stored in the interface i. ValueOf(nil) returns the zero Value.
Elem returns the value that the interface v contains or that the pointer v points to. It panics if v's Kind is not Interface or Ptr. It returns the zero Value if v is nil.
I found this code from a post on stackoverflow but still don't understand when to use .Elem()
func SetField(obj interface{}, name string, value interface{}) error {
// won't work if I remove .Elem()
structValue := reflect.ValueOf(obj).Elem()
structFieldValue := structValue.FieldByName(name)
if !structFieldValue.IsValid() {
return fmt.Errorf("No such field: %s in obj", name)
}
if !structFieldValue.CanSet() {
return fmt.Errorf("Cannot set %s field value", name)
}
structFieldType := structFieldValue.Type()
// won't work either if I add .Elem() to the end
val := reflect.ValueOf(value)
if structFieldType != val.Type() {
return fmt.Errorf("Provided value %v type %v didn't match obj field type %v",val,val.Type(),structFieldType)
}
structFieldValue.Set(val)
return nil
}
reflect.ValueOf() is a function, think of it as the entry point to reflection. When you have a "non-reflection" value, such as a string or int, you can use reflect.ValueOf() to get a reflect.Value descriptor of it.
Value.Elem() is a method of reflect.Value. So you can only use this if you already have a reflect.Value. You may use Value.Elem() to get the value (reflect.Value) pointed by the value wrapped by the original reflect.Value. Note that you may also use reflect.Indirect() for this. There's another "use case" for Value.Elem(), but it's more "advanced", we return to it at the end of the answer.
To "leave" reflection, you may use the general Value.Interface() method, which returns you the wrapped value as an interface{}.
For example:
var i int = 3
var p *int = &i
fmt.Println(p, i)
v := reflect.ValueOf(p)
fmt.Println(v.Interface()) // This is the p pointer
v2 := v.Elem()
fmt.Println(v2.Interface()) // This is i's value: 3
This will output (try it on the Go Playground):
0x414020 3
0x414020
3
For a great introduction to Go's reflection, read The Go Blog: The Laws of Reflection. Although if you're just starting with Go, I'd focus on other things and leave reflection for a later adventure.
Another use case for Value.Elem()
This is kind of an advanced topic, so don't freak out if you don't understand it. You don't need to.
We saw how Value.Elem() can be used to "navigate" when a pointer is wrapped in the reflect.Value. Doc of Value.Elem() says:
Elem returns the value that the interface v contains or that the pointer v points to.
So if reflect.Value wraps an interface value, Value.Elem() may also be used to get the concrete value wrapped in that interface value.
Interfaces in Go is its own topic, for the internals, you may read Go Data Structures: Interfaces by Russ Cox. Again, not necessarily a topic for Go starters.
Basically whatever value you pass to reflect.ValueOf(), if it's not already an interface value, it will be wrapped in an interface{} implicitly. If the passed value is already an interface value, then the concrete value stored in it will be passed as a interface{}. This second "use case" surfaces if you pass a pointer to interface (which is otherwise very rare in Go!).
So if you pass a pointer to interface, this pointer will be wrapped in an interface{} value. You may use Value.Elem() to get the pointed value, which will be an interface value (not a concrete value), and using Value.Elem() again on this will give you the concrete value.
This example illustrates it:
var r io.Reader = os.Stdin // os.Stdin is of type *os.File which implements io.Reader
v := reflect.ValueOf(r) // r is interface wrapping *os.File value
fmt.Println(v.Type()) // *os.File
v2 := reflect.ValueOf(&r) // pointer passed, will be wrapped in interface{}
fmt.Println(v2.Type()) // *io.Reader
fmt.Println(v2.Elem().Type()) // navigate to pointed: io.Reader (interface type)
fmt.Println(v2.Elem().Elem().Type()) // 2nd Elem(): get concrete value in interface: *os.File
Try it on the Go Playground.
I was recently playing with the Go language and I bumped into something a bit weird to say the least, let's consider a very simple function:
func main() {
n, e := fmt.Println(`He said: "Hello"`)
fmt.Printf("%T\n", n)
}
Which outputs what I was expecting:
He said: "Hello"
int
Now if I want to display the type of e:
func main() {
n, e := fmt.Println(`He said: "Hello"`)
fmt.Printf("%T\n", e)
}
and this time prints out:
He said: "Hello"
<nil>
I get the part that there is no error so e is an empty pointer: nil but I would have not expected to be a ~~type~~ on its own.
Why am I not getting the actual type?
If so, is there a workaround? (not saying my use case is a realistic one but curious if there is any possibility)
The Go Programming Language Specification
Errors
The predeclared type error is defined as
type error interface {
Error() string
}
It is the conventional interface for representing an error condition,
with the nil value representing no error.
Interface types
An interface type specifies a method set called its interface. A
variable of interface type can store a value of any type with a method
set that is any superset of the interface. Such a type is said to
implement the interface. The value of an uninitialized variable of
interface type is nil.
The zero value
When storage is allocated for a variable, either through a declaration
or a call of new, or when a new value is created, either through a
composite literal or a call of make, and no explicit initialization is
provided, the variable or value is given a default value. Each element
of such a variable or value is set to the zero value for its type: nil
for interfaces.
A zero-value error type, an interface, has no type.Its value is nil.
e is an empty pointer
Nope, error itself - interface, so you won't have type here.
Below is a piece of Go code I have question about.
Specifically, what is a in this function?
func DPrintf(format string, a ...interface{}) (n int, err error) {
if Debug > 0 {
n, err = fmt.Printf(format, a...)
}
return
}
Could anyone tell me what the three dots are here?
And what does ...interface{} do?
A parameter type prefixed with three dots (...) is called a variadic parameter. That means you can pass any number or arguments into that parameter (just like with fmt.Printf()). The function will receive the list of arguments for the parameter as a slice of the type declared for the parameter ([]interface{} in your case). The Go Specification states:
The final parameter in a function signature may have a type prefixed with .... A function with such a parameter is called variadic and may be invoked with zero or more arguments for that parameter.
A parameter:
a ...interface{}
Is, for the function equivalent to:
a []interface{}
The difference is how you pass the arguments to such a function. It is done either by giving each element of the slice separately, or as a single slice, in which case you will have to suffix the slice-value with the three dots. The following examples will result in the same call:
fmt.Println("First", "Second", "Third")
Will do the same as:
s := []interface{}{"First", "Second", "Third"}
fmt.Println(s...)
This is explained quite well in the Go Specification as well:
Given the function and calls
func Greeting(prefix string, who ...string)
Greeting("nobody")
Greeting("hello:", "Joe", "Anna", "Eileen")
within Greeting, who will have the value nil in the first call, and []string{"Joe", "Anna", "Eileen"} in the second.
If the final argument is assignable to a slice type []T, it may be passed unchanged as the value for a ...T parameter if the argument is followed by .... In this case no new slice is created.
Given the slice s and call
s := []string{"James", "Jasmine"}
Greeting("goodbye:", s...)
within Greeting, who will have the same value as s with the same underlying array.
As far as the interface{} term, it is the empty interface. In other words, the interface implemented by all variables in Go.
This is sort of analogous to java.lang.Object or System.Object in C#, but is instead inclusive of every variable type in the language. So it lets you pass in anything to the method.
Why don't I have to define PrintValue() as a pointer receiver (*One) to be able to print "hello"?
package main
import "fmt"
type One struct{
a string
}
func (o *One)AssignValue(){
o.a = "hello"
}
func (o One)PrintValue(){
fmt.Println(o.a)
}
func main() {
one := One{}
one.AssignValue()
one.PrintValue()
}
Because one is already of type One. The instantiation syntax
t := One{}
creates a value of type One while the form
p := &One{}
creates a pointer to a value of type One.
This means that nothing is to be done when calling t.PrintValue as the receiver type (One) is already the same as the type of t (One as well).
When calling p.PrintValue the compiler automatically converts an addressable variable to its pointer form because the receiver type (One) is not equal to the type of p (*One). So the expression
p.PrintValue()
is converted to
(*p).PrintValue()
There is also a conversion necessary when calling t.AssignValue as this method has a pointer receiver but we're supplying a value. This is also done automatically by the compiler where possible.
From the spec on calls:
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()
This means the expression
t.AssignValue()
is converted to
(&t).AssignValue()
Note that this is not always possible. For example when returning a value from a function:
func NewOne(s string) One { return One{s} }
NewOne("foo").AssignValue() // Not possible
x := NewOne("foo")
x.AssignValue() // Possible, automatically converted
Suppose I have the following code:
package main
import "fmt"
type Car struct{
year int
make string
}
func (c *Car)String() string{
return fmt.Sprintf("{make:%s, year:%d}", c.make, c.year)
}
func main() {
myCar := Car{year:1996, make:"Toyota"}
fmt.Println(myCar)
}
When I call fmt.Println(myCar) and the object in question is a pointer, my String() method gets called properly. If, however the object is a value, my output is formatted using the default formatting built into Go and my code to format the said object is not called.
The interesting thing is in either case if I call myCar.String() manually it works properly whether my object is either a pointer or value.
How can I get my object formatted the way I want no matter if the object is value-based or pointer-based when used with Println?
I don't want to use a value method for String because then that means every time it's invoked the object is copied which seams unreasonable. And I don't want to have to always manually called .String() either because I'm trying to let the duck-typing system do it's work.
When calling fmt.Println, myCar is implicitly converted to a value of type interface{} as you can see from the function signature. The code from the fmt package then does a type switch to figure out how to print this value, looking something like this:
switch v := v.(type) {
case string:
os.Stdout.WriteString(v)
case fmt.Stringer:
os.Stdout.WriteString(v.String())
// ...
}
However, the fmt.Stringer case fails because Car doesn't implement String (as it is defined on *Car). Calling String manually works because the compiler sees that String needs a *Car and thus automatically converts myCar.String() to (&myCar).String(). For anything regarding interfaces, you have to do it manually. So you either have to implement String on Car or always pass a pointer to fmt.Println:
fmt.Println(&myCar)
Methods
Pointers vs. Values
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 is because pointer methods can modify the
receiver; invoking them on a copy of the value would cause those
modifications to be discarded.
Therefore, for your String method to work when invoked on both pointers and values, use a value receiver. For example,
package main
import "fmt"
type Car struct {
year int
make string
}
func (c Car) String() string {
return fmt.Sprintf("{make:%s, year:%d}", c.make, c.year)
}
func main() {
myCar := Car{year: 1996, make: "Toyota"}
fmt.Println(myCar)
fmt.Println(&myCar)
}
Output:
{make:Toyota, year:1996}
{make:Toyota, year:1996}
Define your fmt.Stringer on a pointer receiver:
package main
import "fmt"
type Car struct {
year int
make string
}
func (c *Car) String() string {
return fmt.Sprintf("{maker:%s, produced:%d}", c.make, c.year)
}
func main() {
myCar := Car{year: 1996, make: "Toyota"}
myOtherCar := &Car{year: 2013, make: "Honda"}
fmt.Println(&myCar)
fmt.Println(myOtherCar)
}
Playground
Output:
{maker:Toyota, produced:1996}
{maker:Honda, produced:2013}
Then, always pass a pointer to instances of Car to fmt.Println. This way a potentially expensive value copy is avoided under your control.
The OP further asked:
OP: [when a value receiver is used] "Does this basically mean that if I have a large struct, then every time it goes through Println it will be copied?"
The following experiment is evidence that the answer is "yes" (when a value receiver is used). Note that the String() method increments the year in this experiment, and check how this affects the printed output.
type Car struct {
year int
make string
}
func (c Car) String() string {
s := fmt.Sprintf("{ptr:%p, make:%s, year:%d}", c, c.make, c.year)
// increment the year to prove: is c a copy or a reference?
c.year += 1
return s
}
func main() {
myCar := Car{year: 1996, make: "Toyota"}
fmt.Println(&myCar)
fmt.Println(&myCar)
fmt.Println(myCar)
fmt.Println(myCar)
}
With a value receiver (c Car), the following printed output shows that Go makes value copies of the Car struct, because the year increment is not reflected in subsequent calls to Println:
{ptr:%!p(main.Car={1996 Toyota}), make:Toyota, year:1996}
{ptr:%!p(main.Car={1996 Toyota}), make:Toyota, year:1996}
{ptr:%!p(main.Car={1996 Toyota}), make:Toyota, year:1996}
{ptr:%!p(main.Car={1996 Toyota}), make:Toyota, year:1996}
Changing the receiver to a pointer (c *Car) but changing nothing else, the printed output becomes:
{ptr:0xc420094020, make:Toyota, year:1996}
{ptr:0xc420094020, make:Toyota, year:1997}
{1998 Toyota}
{1998 Toyota}
Even when a pointer is provided as argument in a call to Println, i.e. fmt.Println(&myCar), Go still makes a value copy of the Car struct when a value receiver is used. The OP wants to avoid value copies being made, and my conclusion is that only pointer receivers satisfy that requirement.
It's only related to implementation of fmt instead of Go however.
String() with pointer receiver would be invoked by https://github.com/davecgh/go-spew since spew print things in this way:
v = reflect.ValueOf(arg)
...
switch iface := v.Interface().(type) {
case fmt.Stringer:
defer catchPanic(w, v)
if cs.ContinueOnMethod {
w.Write(openParenBytes)
w.Write([]byte(iface.String()))
w.Write(closeParenBytes)
w.Write(spaceBytes)
return false
}
w.Write([]byte(iface.String()))
return true
}
Generally speaking, it's best to avoid assigning values to variables via static initializers, i.e.
f := Foo{bar:1,baz:"2"}
This is because it can create exactly the complaint you're talking about, if you forget to pass foo as a pointer via &foo or you decide to use value receivers you end up making a lot of clones of your values.
Instead, try to assign pointers to static initializers by default, i.e.
f := &Foo{bar:1,baz:"2"}
This way f will always be a pointer and the only time you'll get a value copy is if you explicitly use value receivers.
(There are of course times when you want to store the value from a static initializer, but those should be edge cases)