Golang, convert nil pointer of struct to error, but not get nil value [duplicate] - pointers

I fail to understand how to correctly assure that something is not nil in this case:
package main
type shower interface {
getWater() []shower
}
type display struct {
SubDisplay *display
}
func (d display) getWater() []shower {
return []shower{display{}, d.SubDisplay}
}
func main() {
// SubDisplay will be initialized with null
s := display{}
// water := []shower{nil}
water := s.getWater()
for _, x := range water {
if x == nil {
panic("everything ok, nil found")
}
// First iteration display{} is not nil and will
// therefore work, on the second iteration
// x is nil, and getWater panics.
x.getWater()
}
}
The only way I found to check if that value is actually nil is by using reflection.
Is this really wanted behaviour? Or do I fail to see some major mistake in my code?
Play link here

The problem here is that shower is an interface type. Interface types in Go hold the actual value and its dynamic type. More details about this: The Laws of Reflection #The representation of an interface.
The slice you return contains 2 non-nil values. The 2nd value is an interface value, a (value;type) pair holding a nil pointer value and a *display concrete type. Quoting from the Go Language Specification: Comparison operators:
Interface values are comparable. Two interface values are equal if they have identical dynamic types and equal dynamic values or if both have value nil.
So if you compare it to nil, it will be false. If you compare it to an interface value representing the pair (nil;*display), it will be true:
if x == (*display)(nil) {
panic("everything ok, nil found")
}
This seems unfeasible as you'd have to know the actual type the interface holds. But note that you can use reflection to tell if a non-nil interface value wraps a nil value using Value.IsNil(). You can see an example of this on the Go Playground.
Why is it implemented this way?
Interfaces unlike other concrete types (non-interfaces) can hold values of different concrete types (different static types). The runtime needs to know the dynamic or runtime-type of the value stored in a variable of interface type.
An interface is just a method set, any type implements it if the same methods are part of the method set of the type. There are types which cannot be nil, for example a struct or a custom type with int as its underlying type. In these cases you would not need to be able to store a nil value of that specific type.
But any type also includes concrete types where nil is a valid value (e.g. slices, maps, channels, all pointer types), so in order to store the value at runtime that satisfies the interface it is reasonable to support storing nil inside the interface. But besides the nil inside the interface we must store its dynamic type as the nil value does not carry such information. The alternate option would be to use nil as the interface value itself when the value to be stored in it is nil, but this solution is insufficient as it would lose the dynamic type information.
Some people say that Go's interfaces are dynamically typed, but that is misleading. They are statically typed: a variable of interface type always has the same static type, and even though at run time the value stored in the interface variable may change type, that value will always satisfy the interface.
In general if you want to indicate nil for a value of interface type, use explicit nil value and then you can test for nil equality. The most common example is the built-in error type which is an interface with one method. Whenever there is no error, you explicitly set or return the value nil and not the value of some concrete (non-interface) type error variable (which would be really bad practice, see demonstration below).
In your example the confusion arises from the facts that:
you want to have a value as an interface type (shower)
but the value you want to store in the slice is not of type shower but a concrete type
So when you put a *display type into the shower slice, an interface value will be created, which is a pair of (value;type) where value is nil and type is *display. The value inside the pair will be nil, not the interface value itself. If you would put a nil value into the slice, then the interface value itself would be nil and a condition x == nil would be true.
Demonstration
See this example: Playground
type MyErr string
func (m MyErr) Error() string {
return "big fail"
}
func doSomething(i int) error {
switch i {
default:
return nil // == nil
case 1:
var p *MyErr
return p // != nil
case 2:
return (*MyErr)(nil) // != nil
case 3:
var p *MyErr
return error(p) // != nil because the interface points to a
// nil item but is not nil itself.
case 4:
var err error // == nil: zero value is nil for the interface
return err // This will be true because err is already interface type
}
}
func main() {
for i := 0; i <= 4; i++ {
err := doSomething(i)
fmt.Println(i, err, err == nil)
}
}
Output:
0 <nil> true
1 <nil> false
2 <nil> false
3 <nil> false
4 <nil> true
In case 2 a nil pointer is returned but first it is converted to an interface type (error) so an interface value is created which holds a nil value and the type *MyErr, so the interface value is not nil.

Let's think of an interface as a pointer.
Say you have a pointer a and it's nil, pointing to nothing.
var a *int // nil
Then you have a pointer b and it's pointing to a.
var b **int
b = &a // not nil
See what happened? b points to a pointer that points to nothing. So even if it's a nil pointer at the end of the chain, b does point to something - it isn't nil.
If you'd peek at the process' memory, it might look like this:
address | name | value
1000000 | a | 0
2000000 | b | 1000000
See? a is pointing to address 0 (which means it's nil), and b is pointing to the address of a (1000000).
The same applies to interfaces (except that they look a bit different in memory).
Like a pointer, an interface pointing to a nil pointer would not be nil itself.
Here, see for yourself how this works with pointers and how it works with interfaces.

I'll take an alternative route to answer your concrete question, by providing the exact answer you were looking for:
Replace the check:
if x == nil {
panic("everything is ok. nil found")
}
with:
if _, ok := x.(display); !ok {
panic("everything is ok. nil found")
}
The idea here is that we are trying to convert the interface type (shower) to the concrete type display. Obviously the second slice item (d.SubDisplay) is not.

Related

Nil pointer to struct not deep equal to nil?

If I have a struct containing a nil pointer of type A, using reflect.DeepEqual to check if that property is nil will result in false, which strikes me as odd behaviour.
type Container struct {
O *Obj
}
type Obj struct {
Message string
}
var c Container
eq := reflect.DeepEqual(c.O, nil)
fmt.Printf("O value: %v, is nil: %t", c.O, eq)
// Prints: "O value: <nil>, is nil: false"
Specifically, I am marshaling a JSON object into a struct, where I would like to test that a specific property is nil when the corresponding JSON structure does not contain it. If reflect.DeepEqual is not the way to go, how should I do this?
Everything you pass to reflect.DeepEqual() is wrapped in an interface{} value (if it's not already that):
func DeepEqual(x, y interface{}) bool
interface{} values will be compared, where the first parameter value is not nil, only the value wrapped in it.
An interface value is represented as a (type; value) pair. The first value you pass to reflect.DeepEqual() is a pair of (type; value) being (*Obj, nil), and the 2nd value is nil. They are not equal. The second value lacks type information.
If you compare it to a "typed" nil, it will be true:
reflect.DeepEqual(c.O, (*Obj)(nil)) // This is true
See this example:
fmt.Println("c.O:", c.O)
fmt.Println("c.O == nil:", c.O == nil)
fmt.Println("c.O deep equal to nil:", reflect.DeepEqual(c.O, nil))
fmt.Println("c.O deep equal to (*Obj)(nil):", reflect.DeepEqual(c.O, (*Obj)(nil)))
Output (try it on the Go Playground):
c.O: <nil>
c.O == nil: true
c.O deep equal to nil: false
c.O deep equal to (*Obj)(nil): true
See this question for a deeper insight:
Hiding nil values, understanding why golang fails here
If you want to check if the value wrapped inside a non-nil interface is nil, you can use reflection: reflect.Value.IsNil().
For more details see: Why interface type doesn't provide an "IsNil" method?

Check if interface value is nil in Go without using reflect

I need to check if an interface value is `nil.
But by using reflection it is giving me an error:
reflect: call of reflect.Value.Bool on struct Value.
Through nil it is not giving an error for nil value.
Interface is a pair of (type, value), when you compare a interface with nil, you are comparing the pair (type, value) with nil. To just compare interface value, you either have to convert it to a struct (through type assertion) or use reflection.
do a type assertion when you know the type of the interface
if i.(bool) == nil {
}
otherwise, if you don't know the underlying type of the interface, you may have to use reflection
if reflect.ValueOf(i).IsNil() {
}
There are two things:
If y is the nil interface itself (in which case y==nil will be true), or if y is a non-nil interface but underlying value is a nil value (in which case y==nil will be false).
Here's an example.

Concise nil checks for struct field pointers?

Say I have this struct:
type Foo struct {
Bar *string `json:"bar"`
Baz *int64 `json:"baz,omitempty"`
Qux *string `json:"qux"`
Quux string `json:"quux"`
}
After unmarshalling the json, I check for nil like so:
switch {
case f.Bar == nil:
return errors.New("Missing 'bar'")
case f.Baz == nil:
f.Baz = 42
case f.Qux == nil:
return errors.New("Missing 'qux'")
}
(or through a series of if statements, etc...)
I understand that I can put all the nil comparisons in one comma separated case, but each nil check will have differing returns.
My question: is there a less verbose way of doing the nil checks?
A question to you: how less verbose you want to get? Because you want to do different things on different conditions (different fields being nil). Your code contains these different things and the different conditions. Beyond that what's "redundant" in your code are just the switch and case keywords. You want to leave them out? Because the rest is not "redundant", they are required.
Also note that in Go cases do not fall through even without a break (unlike in other languages), so in your above example if f.Baz is nil, you will set it to 42 and f.Qux will not be checked (so no error will be returned), but if f.Baz is non-nil and f.Qux is nil, an error will be returned. I know it's just an example, but this is something to keep in mind. You should handle errors first if you use a switch! Or use if statements and then the error will be detected and returned regardless of the order of field checks.
Your code with switch is clean and efficient. If you want to make it less verbose, readability (and performance) will suffer.
You may use a helper function which checks if a pointer value is nil:
func n(i interface{}) bool {
v := reflect.ValueOf(i)
return v.Kind() == reflect.Ptr && v.IsNil()
}
And using it:
func check(f *Foo) error {
switch {
case n(f.Bar):
return errors.New("Missing 'bar'")
case n(f.Qux):
return errors.New("Missing 'qux'")
case n(f.Baz):
x := int64(42)
f.Baz = &x
}
return nil
}
Or using if statements:
func check2(f *Foo) error {
if n(f.Bar) {
return errors.New("Missing 'bar'")
}
if n(f.Qux) {
return errors.New("Missing 'qux'")
}
if n(f.Baz) {
x := int64(42)
f.Baz = &x
}
return nil
}
Try these on the Go Playground.

Set an interface to nil in Golang

I'm trying to set an internal value of an interface to nil something like the following :
typ := &TYP{InternalState: "filled"}
setNil(typ)
fmt.Printf("Expecting that %v to be nil", typ)
And I need to know how to implement the setNil(typ interface{}) method.
For more details see this code in play.golang.org.
The thing is you don't have an interface value. You have a pointer value, a pointer to a concrete type. That is not the same as an interface value.
If you want to change the value of a variable of any type, you have to pass a pointer to it. This also includes variables of interface type, and also variables of pointer type. This is one of those very rare cases when a pointer to interface{} makes sense (*interface{}), in fact it's inevitable.
But if your function expects an interface and you pass a non-interface value, an interface value will be created implicitly and you could only nil this implicitly created value.
So we have 2 different / distinct cases:
Function to nil an interface{}
func setNilIf(v *interface{}) {
*v = nil
}
Using it:
var i interface{} = "Bob"
fmt.Printf("Before: %v\n", i)
setNilIf(&i)
fmt.Printf("After: %v\n", i)
Output:
Before: Bob
After: <nil>
So it works.
Function to nil a pointer; using unsafe
Actually this is your case. We want to change the value of a variable of pointer type. To accept a pointer to any type, we can use unsafe.Pointer. unsafe.Pointer is a language support, it's a special pointer type which can be converted from and to any pointer type.
We want to accept the address (pointer) of the pointer variable, which is something like **SomeType. To actually be able to assign a new value (nil) to the pointer variable, we have to dereference it (* operator). But unsafe.Pointer cannot be dereferenced, so first we have to convert it to a pointer to pointer to "something", but since we only want to assign nil (which is the same to all pointer types regardless of the type of the pointed value), the "something" doesn't matter, I will just use int, and so I will convert the unsafe.Pointer pointer value to **int.
func setNilPtr(p unsafe.Pointer) {
*(**int)(p) = nil
}
Using it:
typ := &TYP{InternalState: "filled"}
fmt.Printf("Before: %v\n", typ)
setNilPtr(unsafe.Pointer(&typ))
fmt.Printf("After: %v\n", typ)
Output:
Before: &{filled}
After: <nil>
So this one also works. There is still another way using reflection:
Function to nil a pointer; using reflect
You can also nil a pointer using reflection only (reflect package). We still have to pass the address of the variable of pointer type. Note that in this case the type of the parameter will simply be interface{}. And it will contain a dynamic type like **SomeType. Since pointers have zero value nil, we can obtain such a value with reflect.Zero() which we will set using Value.Set():
func setNilPtr2(i interface{}) {
v := reflect.ValueOf(i)
v.Elem().Set(reflect.Zero(v.Elem().Type()))
}
Using it:
typ2 := &TYP{InternalState: "filled"}
fmt.Printf("Before: %v\n", typ2)
setNilPtr2(&typ2)
fmt.Printf("After: %v\n", typ2)
Output:
Before: &{filled}
After: <nil>
So this one also works. Try these on the Go Playground.
But seriously: if you want to nil something, assign nil to it. Do not complicate things unnecessarily.
i = nil
typ = nil

Go : doubly linked list implementing panic error

Correction:
Link #1 http://play.golang.org/p/CKRNyWYF8X
Link #2 http://play.golang.org/p/oT2yKzFwep
From the first link,
I am sure that the panic error comes from this
func (A *DoublyLinkedList) AddHead(input_value interface{}) {
temp_node := &Node{value: input_value, prev: nil, next: A.head}
original_head_node := A.head
original_head_node.prev = temp_node
A.length++
}
But when I use this for doubly linked list, it panics little later. And still fails because this one below does not connect the original head with previous pointer.
func (A *DoublyLinkedList) AddHead(input_value interface{}) {
A.head = NewNode(input_value, nil, A.head)
A.length++
}
This is the one. This one has the similar problem.
cannot assign to target_node.GetPrevNode().GetNextNode()
Does go not support pointer reference this way? I did fix this just assigning a new variable every time I need to get the pointer. But my first question on the top still does not compile.
In short, how do I connect the doubly linked list when adding a new element in Go?
You need to initialize the properties inside the DoublyLinkedList. It seems to me, you are currently creating a reference to it in NewDoublyLinkedList() with 2 nil properties.
type DoublyLinkedList struct {
head *Node // nil
tail *Node // nil
length int
}
And when doing this
original_head_node := A.head // A.head == nil
original_head_node.prev = temp_node // You are trying to access a property in nil

Resources