Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

encoding/json: Unmarshal an interface pointer bug #21494

Closed
ghost opened this issue Aug 17, 2017 · 2 comments
Closed

encoding/json: Unmarshal an interface pointer bug #21494

ghost opened this issue Aug 17, 2017 · 2 comments

Comments

@ghost
Copy link

@ghost ghost commented Aug 17, 2017

go version
go1.8.3 linux/amd64

go env
GOARCH="amd64"
GOBIN=""
GOEXE=""
GOHOSTARCH="amd64"
GOHOSTOS="linux"
GOOS="linux"
GOPATH="/home/xing/go"
GORACE=""
GOROOT="/usr/local/go"
GOTOOLDIR="/usr/local/go/pkg/tool/linux_amd64"
GCCGO="gccgo"
CC="gcc"
GOGCCFLAGS="-fPIC -m64 -pthread -fmessage-length=0 -fdebug-prefix-map=/tmp/go-build248645349=/tmp/go-build -gno-record-gcc-switches"
CXX="g++"
CGO_ENABLED="1"
PKG_CONFIG="pkg-config"
CGO_CFLAGS="-g -O2"
CGO_CPPFLAGS=""
CGO_CXXFLAGS="-g -O2"
CGO_FFLAGS="-g -O2"
CGO_LDFLAGS="-g -O2"

type Test struct{
	A string
	B string
}

func main(){
	a := Test{"12","23"}
	b := reflect.New(reflect.TypeOf(a)).Elem().Interface()
	c,err := json.Marshal(a)
	if err != nil {
		log.Fatal(err)
	}
	json.Unmarshal(c,&b)
	fmt.Printf("%#v", b)
}
result : 
map[string]interface {}{"A":"12", "B":"23"}

So we can see json.Unmarshal will change the type of 'b' from Test to map[string]interface{}

Reason :
encoding/json/decode.go function indirect (line 439)

if v.Kind() == reflect.Interface && !v.IsNil() {
			e := v.Elem()
			if e.Kind() == reflect.Ptr && !e.IsNil() && (!decodingNull || e.Elem().Kind() == reflect.Ptr) {
				v = e
				continue
			}
                        //maybe you can check the e.Kind() here
		}

Thanks

@cznic

This comment has been minimized.

Copy link
Contributor

@cznic cznic commented Aug 17, 2017

@ianlancetaylor ianlancetaylor changed the title json: Unmarshal an interface pointer bug encoding/json: Unmarshal an interface pointer bug Aug 17, 2017
@ianlancetaylor

This comment has been minimized.

Copy link
Contributor

@ianlancetaylor ianlancetaylor commented Aug 17, 2017

This is happening because the type of b is interface{}, so the type of &b, which you pass to json.Unmarshal, is type *interface{}. Unmarshal isn't changing the type, it's using the type you give it.

Closing because I don't think there is anything to fix here. Please comment if you disagree.

@golang golang locked and limited conversation to collaborators Aug 17, 2018
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Linked pull requests

Successfully merging a pull request may close this issue.

None yet
3 participants
You can’t perform that action at this time.