Go: nil == nil is true or false? Na tum jano na hum…
Published: 2022-04-16 08:23:54


![Go image](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/wz0vkmmn15wl0h9feaim.jpeg)
In this article, we will understand how to use `==` the operator in Go to compare object values. We will also look at scenarios where the behaviour of this operator looks like a bug in the language but it is due to a lack of understanding.

Let's go through the below example

```
var a *string = nil    
var b interface{} = a
fmt.Println("a == nil:", a == nil) // true 
fmt.Println("b == nil:", b == nil) // false 
fmt.Println("a == b:  ", a == b  ) // true
```

To understand the above example lets start with a simple one:
```
var a int = 12
var b int = 12
c:= 12
fmt.Println("a == b :", a == b) // true
fmt.Println("a == c :", a == c) // true
```

This is very obvious.
**Let's twist the example**
```
var a *string = nil
var b interface{} = nil
fmt.Println("a == nil:", a == nil) // true
fmt.Println("b == nil:", b == nil) // true
fmt.Println("a == b:",   a == b) // false (even though the value is
                                           nil for both a and b)
```

To understand the last case, let us dive deeper into it.

In Go, every pointer variable has two values associated with it `<type, value>` The fact that every variable needs a type is the reason why we can not have a nil value assigned to a variable whose type is not defined. That's why we can not write `x := nil` because we don't mention the type of x and we get the following error `use of untyped nil`

**Now let's see our problem again**
```
var a *string = nil      // a is <*string, nil>
var b interface{} = nil  // b is <nil, nil>
fmt.Println("a == nil:", a == nil) // true
fmt.Println("b == nil:", b == nil) // true
fmt.Println("a == b:", a == b)    // false <*string,nil>!=<nil, nil>
```
In our case variable `a` actually represent `<*string, nil>` and `interface{}` default type is `nil` so variable `b` is `<nil, nil>`.
So that's why when we say `a == b` then we are actually comparing `<*string,nil> == <nil, nil>` which is false.

Now come back to our main example
```
var a *string = nil     // a is <*string, nil>
var b interface{} = a 
fmt.Println("a ==nil:",a==nil)//true(<*string, nil>==<*string, nil>)
fmt.Println("b == nil:", b == nil) //false (<*string,nil>==<nil,nil>    fmt.Println("a == b:  ", a == b  ) // true
```

When we do `a == nil` , `==` the operator compares type as well as value. Here the value is nil for both LHS and RHS, but what will be the type of nil ???

When nil(hard-coded value) is compared with an object, the type of nil is the same as the declaration type of object with whom it is compared.

So in the case of `a == nil` we are doing `<*string, nil> == <*string, nil>`

In the case of `b == nil` , RHS is `<nil, nil>` because the declaration type of `b` is interface{} which is nil (default). Hence when we did
```
var b interface{} = a
```
Then we assigned the value of `a` to variable `b` which means `b` now refers to `<*string, nil>` . Hence `LHS != RHS`

**Note**: `var b interface{} = a` does not change the declaration type of `b` variable.

## **Conclusion**
This issue occurs frequently in industrial code like below code snippet is very common in Go where we can face such error.
```
var resp string
var err error
resp, err = CallFunction()
if err != nil{
   // code inside this if statement will be executed if return type  of CallFunction doesn't match with error
}
func CallFunction() custom.Error{
 // return pointer variable
}
```

Here is the playground for more experimentation https://play.golang.org/p/BnPPXEs9_Oq

So it's always better to check that the return type of called function and type of receiving variables in the caller function should match.