I'm new to golang. I'm starting with a tour of go. Here is the go playground link
Here is the code :
package main
import "fmt"
type I interface {
M()
}
type T struct {
S string
}
func (t *T) M() {
fmt.Println(t.S)
}
func main() {
var i I
var t *T
i = t
i.M()
}
It is panicing
panic: runtime error: invalid memory address or nil pointer dereference [signal SIGSEGV: segmentation violation code=0xffffffff addr=0x0 pc=0xd3ea6] goroutine 1 [running]: main.(*T).M(0x0, 0x434070) /tmp/sandbox696069628/main.go:15 +0x26 main.main() /tmp/sandbox696069628/main.go:24 +0x40
However when I change
var t *T
i = t
to
var t T
i = &t
It does not panic anymore
Shouldn't the behavior be similar in both cases. If not, why?
You are declaring, but not explicitly defining a variable named t
in both cases. If you don't specify a value, the zero value for the variable's type is assigned
The zero value for all pointer types, including *T
is nil. The zero value for a struct type is a value of that struct with all fields set to their zero values.
When storage is allocated for a variable [...] 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: false for booleans, 0 for numeric types, "" for strings, and nil for pointers, functions, interfaces, slices, channels, and maps. This initialization is done recursively, so for instance each element of an array of structs will have its fields zeroed if no value is specified.
https://golang.org/ref/spec#The_zero_value
Consequently this stores nil in the interface value i
:
var i interface{ M() }
var t *T
i = t
// i stores nil
And this stores a struct value in the interface value i
:
var i interface{ M() }
var t T
i = t
// i stores T{S:""}
So in the first case, (nil).M()
is called (which panics), and in the second case (T{}).M()
is called.
You didn't initialized T.
Do this :
var t *T = &T{"Hello World"}
User contributions licensed under CC BY-SA 3.0