golang (*interface{})(nil) is nil or not? - go

the code snippet is the following:
package main
import (
"fmt"
"reflect"
)
func main() {
a := (*interface{})(nil)
fmt.Println(reflect.TypeOf(a), reflect.ValueOf(a))
var b interface{} = (*interface{})(nil)
fmt.Println(reflect.TypeOf(b), reflect.ValueOf(b))
fmt.Println(a == nil, b == nil)
}
the output like below:
*interface {} <nil>
*interface {} <nil>
true false
so var interface{} is different from :=,why?

according to golang faq
Under the covers, interfaces are implemented as two elements, a type and a value. The value, called the interface's dynamic value, is an arbitrary concrete value and the type is that of the value. For the int value 3, an interface value contains, schematically, (int, 3).
An interface value is nil only if the inner value and type are both unset, (nil, nil). In particular, a nil interface will always hold a nil type. If we store a nil pointer of type *int inside an interface value, the inner type will be *int regardless of the value of the pointer: (*int, nil). Such an interface value will therefore be non-nil even when the pointer inside is nil.
a := (*interface{})(nil) is equal with var a *interface{} = nil.
but var b interface{} = (*interface{})(nil) , mean b is type interface{}, and interface{} variable only nil when it's type and value are both nil, obviously type *interface{} is not nil.

Related

Behaviour of nil receiver in method in Golang

package main
import (
"fmt"
)
type I interface {
M()
}
type T struct {
}
func (t *T) M() {
fmt.Println(t == nil)
}
func main() {
var i I
var t *T
i = t
fmt.Println(i == nil)
i.M()
}
The result is false and true.
The value in both cases is nil and type is *main.T.
I understand that in the first case i == nil is false because the variable i does not have a nil type.
I do not understand why t == nil is true inside the method M().
In the first case, i==nil is false, because i is an interface whose type is T and whose value is nil. For an interface to be equal to the literal value nil, it has to have both type and value nil. Here, i has non-nil type.
In the second case, the receiver is simply nil, because the receiver of the function M is a value of type *T whose value is nil.

Interfaces can be of type nil but that doesn't mean they are nil?

I wrote a bit of code that in effect does this:
package main
import "fmt"
type SomeInterface interface {
Retrieve(identifier string)
}
type SomeStruct struct {}
func (r SomeStruct) Retrieve(identifier string) {
fmt.Println("identifier ", identifier)
}
type Handler struct {
Name string
SomeObject SomeInterface
}
func main() {
var someStruct *SomeStruct
var h = Handler{
Name: "helo",
SomeObject: someStruct,
}
fmt.Printf("before %+v\r\n", h.SomeObject)
if h.SomeObject == nil {
fmt.Printf("during %+v\r\n", h.SomeObject)
}
fmt.Printf("after %+v\r\n", h.SomeObject)
}
Please can someone explain to me why the output of the above is:
before <nil>
after <nil>
I've been reading about interfaces of type nil but in this case I have assigned the interface to a pointer that hasn't been assigned so I would have thought that the interface == nil and I would see during <nil> - alas it is not the case.
An interface value is a simple data structure with two parts, a type and an underlying value. So, the interface value itself can be nil, or the interface value can exist but the underlying value can be nil. For example:
var x interface{} = nil // x is nil
var y interface{} = (interface{})(nil) // y is a interface{}, which *contains* nil
This is in some ways conceptually similar to this difference:
var x []*int = nil // x is nil
var y []*int = []*int{nil} // y is a []*int, which *contains* nil
fmt.Printf obscures the difference in the case of an interface because of the way it formats the output; you could see the difference more clearly using reflection if you wanted to.
SomeObject is not nil, it just points to SomeStruct which is nil.
i think the confusion is fmt.Printf prints <nil> for this case cuz it's following the pointer and that end result is nil.
In Go, a variable referring to an implementer of some interface can have many types. It can be of type <nil> (yes, nil can describe a type as well as a value), it can be the type of one of its implementers, or it can be the type of a pointer to one of its implementers. By default, a variable referring to an interface is of type nil. Once you've assigned something to it (other than nil itself), it will then take on the type of the thing you've assigned to it (again, either the type of one of its implementers, or a pointer to one of those types).
You can print the type of an interface variable with %T, and its value with %v:
func main() {
var i SomeInterface
fmt.Printf("%T, %v\n", i, i) // Prints <nil>, <nil>
var someStruct SomeStruct
i = someStruct
fmt.Printf("%T, %v\n", i, i) // Prints main.SomeStruct, {}
var someStructPtr *SomeStruct
i = someStructPtr
fmt.Printf("%T, %v\n", i, i) // Prints *main.SomeStruct, <nil>
}
Now, whenever you compare h.SomeObject == nil, the comparison will only be evaluated as true if both the types and values of the two operands match. In your case, the value of h.SomeObject is clearly <nil> (after all, the value of someStruct is surely <nil>, and you store its value in h.SomeObject). The type of h.SomeObject, based on what I just explaind, must be *SomeStruct. The value of nil is obviously <nil>.
However, what is the type of nil?
Well, nil can take on many types, and the compiler has to decide what type it should take on for each usage. When it comes to comparisons and assignments, it simply takes on the type of the thing it is being compared to or assigned to. For instance, if you are comparing an integer pointer to nil, then the nil in such a case will be of type *int.
But all of this has to be decided at compile time, and a variable referring to an interface can change types during runtime. So when you compare a variable referring to an interface to nil, what type does the compiler give to the nil operand in such a case? Well, it gives it the only sensible type, <nil>.
For a final example, consider the following code:
func main() {
var p *SomeStruct = nil // = nil is optional; pointers default to nil
var i SomeInterface = p
printf("%t\n", p == nil) // Prints true
printf("%t\n", p == i) // Prints true
printf("%t\n", i == nil) // Prints false
}
p == nil is true, since p is of type *SomeStruct with value <nil>, and nil (in this case) is also of type *SomeStruct with value <nil>.
p == i is true, since i is also of type *SomeStruct with value <nil> (it is simply storing the type and value of p).
However, i == nil is false, because nil, in this case, takes on the type <nil> rather than *SomeStruct.
The solution around this problem is simply to never store something of value <nil> in an interface-referring variable, except for nil itself. That way, whenever the value of the interface-referring variable is <nil>, its type will also be <nil>, and comparisons against nil will work as expected. For this reason, you often see code that looks like this:
if p == nil {
i = nil
} else {
i = p
}

how to append nil to dynamic type slice by reflect.Append

Code below will raise a runtime error when append reflect.Value of nil:
package main
import (
"fmt"
"reflect"
)
func main() {
var list []interface{}
v := reflect.ValueOf(list)
v = reflect.Append(v, reflect.ValueOf(1)) // [1]
v = reflect.Append(v, reflect.ValueOf("1")) // [1, 1]
v = reflect.Append(v, reflect.ValueOf(nil)) // runtime error
fmt.Println(v)
}
So
why there is a runtime error?
how can I use reflect.Append to add a nil to interface{} slice?
interface{} is an interface type, and they are "tricky". They are wrappers around a concrete value and the concrete type, schematically a (value, type) pair.
So when you pass a concrete value to a function that expects an interface{} value, the concrete value will be wrapped in an interface{} value automatically, implicitly. If you pass a nil to such a function, the interface value itself will be nil. If you pass a nil pointer to it, such as (*int)(nil), the interface value will not be nil but an interface value holding "(nil, *int)".
If you pass nil to reflect.ValueOf(), it results in a "zero" reflect.Value which represents no value at all. If you pass this to reflect.Append(), it will not have the type information, it will not know what you want to append to the slice.
It is possible to create a value that represents the nil interface value.
To do that, we may start from the type descriptor of a value of an interface pointer (pointers to interface rarely makes sense, but this is one of them). We navigate to the type descriptor of the pointed type, which is interface{}. We obtain a zero value of this type (using reflect.Zero()), which is nil (zero value of interface types is nil).
Zero returns a Value representing the zero value for the specified type. The result is different from the zero value of the Value struct, which represents no value at all.
So this is how it looks like:
typeOfEmptyIface := reflect.TypeOf((*interface{})(nil)).Elem()
valueOfZeroEmptyIface := reflect.Zero(typeOfEmptyIface)
v = reflect.Append(v, valueOfZeroEmptyIface)
Or as a single line:
v = reflect.Append(v, reflect.Zero(reflect.TypeOf((*interface{})(nil)).Elem()))
To check the results, let's use:
fmt.Printf("%#v\n", v)
And also let's type-assert back the slice, and add a nil value using the builtin append() function:
list = v.Interface().([]interface{})
list = append(list, nil)
fmt.Printf("%#v\n", list)
Let's do an explicit, extra check if the elements are nil (compare them to nil). Although using %#v verb this is redundant, %v likes to print non-nil interfaces holding nil concrete values just as nil (the same as if the interface value itself would be nil).
fmt.Println(list[2] == nil, list[3] == nil)
Ouptut will be (try it on the Go Playground):
[]interface {}{1, "1", interface {}(nil)}
[]interface {}{1, "1", interface {}(nil), interface {}(nil)}
true true
See related question: Hiding nil values, understanding why golang fails here
Also: The Go Blog: The Laws of Reflection

Type declaration importance in golang, nil values [duplicate]

This question already has answers here:
Hiding nil values, understanding why Go fails here
(3 answers)
Closed 6 years ago.
I have this small golang test I cannot understand:
package main
import "fmt"
type myObj struct {
}
func nilObj() *myObj {
return nil
}
func nilInt() interface{} {
return nil
}
func main() {
var obj1 interface{}
fmt.Println(obj1 == nil) // true
obj1 = nilObj()
fmt.Println(obj1 == nil) // false
var obj2 *myObj
fmt.Println(obj2 == nil) // true
obj2 = nilObj()
fmt.Println(obj2 == nil) // true
var obj3 interface{}
fmt.Println(obj3 == nil) // true
obj3 = nilInt()
fmt.Println(obj3 == nil) // true
}
Between obj1 and obj2, only the variable declaration changes, but the result is different.
Between obj1 and obj3, the function call does not return the same type (struct pointer vs interface). I am not entirely sure I understand the result.
Any help is welcome (https://play.golang.org/p/JcjsJ-_S8I)
Under the covers, interfaces are implemented as two elements, a type and a value. The value, called the interface's dynamic value, is an arbitrary concrete value and the type is that of the value. For the int value 3, an interface value contains, schematically, (int, 3).
An interface value is nil only if the inner value and type are both unset, (nil, nil). In particular, a nil interface will always hold a nil type. If we store a nil pointer of type *int inside an interface value, the inner type will be *int regardless of the value of the pointer: (*int, nil). Such an interface value will therefore be non-nil even when the pointer inside is nil.
https://golang.org/doc/faq#nil_error

This nil instance of a struct, that satisfies the error interface, is not showing as nil

This should be a gimme for someone. Why do I not get what I expect ("Error is not nil") here?
http://play.golang.org/p/s8CWQxobVL
type Goof struct {}
func (goof *Goof) Error() string {
return fmt.Sprintf("I'm a goof")
}
func TestError(err error) {
if err == nil {
fmt.Println("Error is nil")
} else {
fmt.Println("Error is not nil")
}
}
func main() {
var g *Goof // nil
TestError(g) // expect "Error is nil"
}
This is, it turns out, a Frequently Asked Question about Go, and the short answer is that interface comparisons compare the type and the value, and (*Goof)(nil) and error(nil) have different types.
Since if err != nil is standard, you want a return value that'll work with it. You could declare var err error instead of var g *Goof: err's zero value is conveniently error(nil)
Or, if your func returns an error, return nil will return what you want.
For more background, here's the start of the FAQ's answer:
Under the covers, interfaces are implemented as two elements, a type and a value. The value, called the interface's dynamic value, is an arbitrary concrete value and the type is that of the value. For the int value 3, an interface value contains, schematically, (int, 3).
An interface value is nil only if the inner value and type are both unset, (nil, nil). In particular, a nil interface will always hold a nil type. If we store a pointer of type *int inside an interface value, the inner type will be *int regardless of the value of the pointer: (*int, nil). Such an interface value will therefore be non-nil even when the pointer inside is nil.
And == is strictly checking if the types are identical, not if a type (*Goof) implements an interface (error). Check out the original for more.
If it helps clarify, this doesn't only happen with nil: in this example, the data underlying the x and y variables is obviously 3, but they have different types. When you put x and y into interface{}s, they compare as unequal:
package main
import "fmt"
type Bob int
func main() {
var x int = 3
var y Bob = 3
var ix, iy interface{} = x, y
fmt.Println(ix == iy)
}

Resources