Post

Go lets you do something that feels illegal: shadow `nil`. Yes, `nil` is not a keyword. It is a predeclared identifier, so you can redefine it in a scope, and the compiler will accept it.

In this program: ```go var x any nil := "a" ``` `x` is the zero value for `any`, which is a nil interface value. Then you create a new variable literally named `nil`, holding `"a"`.

0 reposts0 likes

After `nil := "a"`, every `nil` in that scope refers to your string variable, not the built-in `nil`. You did not change the language, you just hid the predeclared identifier behind a local name.

So this line: ```go if x == nil ``` is no longer “is x nil?”. It is “is x equal to the string `a`?”. In other words, it becomes: ```go if x == "a" ```

That comparison is false. `x` is a nil interface value, not a string. So the `panic(nil)` never runs, even though it reads like it should. If it did run, it would panic with `"a"`, because `nil` is your string.

Finally: ```go fmt.Println(x, nil) ``` prints something like: `<nil> a` `x` is still the real nil interface value. `nil` is your local string variable. Same token, different binding.