Where is my type?

118 views
Skip to first unread message

cpu...@gmail.com

unread,
Apr 24, 2024, 12:46:18 PM4/24/24
to golang-nuts
Every time I feel I've come to terms with how Go works I round a corner and hit a wall, even after doing this for >5 years. Here's one.

Consider this simple code (https://go.dev/play/p/bph5I80vc99):

package main

import (
"encoding/json"
"fmt"
)

type S struct {
Foo int
}

func update(v any) {
if err := json.Unmarshal([]byte(`{"Foo": 42}`), &v); err != nil {
panic(err)
}
fmt.Printf("%v %T\n", v, v)
}

func main() {
var val S

// map[Foo:42] map[string]interface {}
update(val)

// &{42} *main.S
update(&val)
}

Why would calling by value change the type of the value passed to map? I would expect an interface with a dynamic type of main.S, but its map[string]interface{}, or json.Unmarshal makes it so.

Insights appreciated :)

burak serdar

unread,
Apr 24, 2024, 12:51:21 PM4/24/24
to cpu...@gmail.com, golang-nuts
In the first case, the interface contains a value of type S, which is
not writable. The value contained in the interface is not addressable.
So Unmarshal creates a new map and fills that. In the second case the
interface contains *S, which is writable, so unmarshal fills it in via
reflection.
> --
> You received this message because you are subscribed to the Google Groups "golang-nuts" group.
> To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts...@googlegroups.com.
> To view this discussion on the web visit https://groups.google.com/d/msgid/golang-nuts/980466d2-1686-4b79-aec1-45b592db2caan%40googlegroups.com.

cpu...@gmail.com

unread,
Apr 24, 2024, 12:52:06 PM4/24/24
to golang-nuts
It's worth noting that before the Unmarshal v is {}(main.S) and afterwards {}(map[string]interface{}) 

cpu...@gmail.com

unread,
Apr 24, 2024, 12:55:53 PM4/24/24
to golang-nuts
> In the first case, the interface contains a value of type S, which is not writable. The value contained in the interface is not addressable.

Thank you for the quick feedback. 
Why is that? Memory for val has been allocated and val is passed by value (hence copied). Why is that copy not be addressable?

cpu...@gmail.com

unread,
Apr 24, 2024, 1:16:49 PM4/24/24
to golang-nuts
Your answer has put me on the right track. Here's the long version: https://stackoverflow.com/questions/48790663/why-value-stored-in-an-interface-is-not-addressable-in-golang
Reply all
Reply to author
Forward
0 new messages