Reputation: 957
I try to check when Golang return a local value as nil, then I use this code.
package main
import (
"fmt"
)
type S struct{}
func InitEfacePointer() interface{} {
var s *S
println(s)
return s
}
func main() {
s := InitEfacePointer()
fmt.Println(s)
//println(s)
}
The output is 0x0
But when I just use println to output value.
package main
type S struct{}
func InitEfacePointer() interface{} {
var s *S
println(s)
return s
}
func main() {
s := InitEfacePointer()
println(s)
}
The output changed to 0x0 (0x93d40,0x0)
Could anyone explain the mechanism of this behavior? Thanks!
Upvotes: 1
Views: 579
Reputation: 21035
You shouldn't be using the builtin println, it clearly states:
The println built-in function formats its arguments in an implementation-specific way and writes the result to standard error. Spaces are always added between arguments and a newline is appended. Println is useful for bootstrapping and debugging; it is not guaranteed to stay in the language.
And the spec also mentions:
Current implementations provide several built-in functions useful during bootstrapping. These functions are documented for completeness but are not guaranteed to stay in the language. They do not return a result.
Implementation restriction: print and println need not accept arbitrary argument types, but printing of boolean, numeric, and string types must be supported.
This is it. print
and println
are useful debugging tools but should not be relied upon to:
That said, I'm guessing that in your case it is printing the internal interface fields: a pointer to a type, and a value.
Upvotes: 3
Reputation: 8212
First of all, fmt.Println
and builtin println
are very different matteres: they are different both in implentation and in purpose. fmt.Println
deals with many complex cases using reflect while println
only deal with some base cases and is only for "bootstrap or debug" (as the spec says).
In this specific case, you are printing an interface{}
you returned from InitEfacePointer()
. The fmt.Println
looks into the interface using reflect and gets the underlying data: a nil pointer to a string and it then prints it out: 0x0
. On the other hand, builtin println
takes the interface and by magic of the compiler (or not), it recognize it is an interface. As this post, golang interface are auctually two pointers, one to information about the type stored and one to the underlying data. So the builtin println
goes into the interface details, 0x93d40
being the "type info" and 0x0
being the underlying data. (The first 0x0
is from the function call).
Furthermore, testing whether the returned interface is nil
seems like a common mistake. Read here: https://golang.org/doc/faq#nil_error
Upvotes: 1