Golang will init all variables (not sometimes, not some):
In your code:
func bar(bts []byte) (a *User) {
err := json.Unmarshal(bts, a) // It will crash
}
You passed a nil pointer but you need a value pointed to by a
, not a nil pointer:
So you may create a Value then store the address of this Value inside a
:
When you use var a *User
or func bar(bts []byte) (a *User)
:
The a
is a pointer to the User
type, and it is initialized to it's zero value, which is nil
,
see (The Go Playground):
package main
import "fmt"
func main() {
var a *User
fmt.Printf("%#v
", a)
}
type User struct {
Name string `json:"Name"`
Age int `json:"Age"`
}
output:
(*main.User)(nil)
And You may use a = &User{}
to initialize it, like this working code (The Go Playground):
package main
import (
"encoding/json"
"fmt"
)
func foo(bts []byte) (*User, error) {
var a User
err := json.Unmarshal(bts, &a) // It's ok
return &a, err
}
func bar(bts []byte) (a *User, err error) {
a = &User{}
err = json.Unmarshal(bts, a) // It's ok
return
}
func main() {
str := `{ "Name": "Alex", "Age": 3 }`
u, err := foo([]byte(str))
if err != nil {
panic(err)
}
fmt.Printf("%#v
", u) // &main.User{Name:"Alex", Age:3}
u, err = bar([]byte(str))
if err != nil {
panic(err)
}
fmt.Printf("%#v
", u) // &main.User{Name:"Alex", Age:3}
}
type User struct {
Name string `json:"Name"`
Age int `json:"Age"`
}
output:
&main.User{Name:"Alex", Age:3}
&main.User{Name:"Alex", Age:3}
Variable declarations:
A variable declaration creates one or more variables, binds
corresponding identifiers to them, and gives each a type and an
initial value.
The initial value (zero value):
When storage is allocated for a variable, either through a declaration
or a call of new, or when a new value is created, either through a
composite literal or a call of make, 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 integers, 0.0
for floats, ""
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.
And see func Unmarshal(data []byte, v interface{}) error
Docs:
Unmarshal parses the JSON-encoded data and stores the result in the
value pointed to by v.