gf icon indicating copy to clipboard operation
gf copied to clipboard

util/gconv: After conversion, the interface{} type becomes *interface {}

Open aundis opened this issue 1 year ago • 11 comments

Go version

go version go1.18 windows/amd64

GoFrame version

v2.7.2

Can this bug be reproduced with the latest release?

Option Yes

What did you do?

package main

import (
	"fmt"

	"github.com/gogf/gf/v2/util/gconv"
)

func main() {
	req := map[string]any{
		"id": "123",
		"doc": map[string]any{
			"craft": nil,
		},
		"fields": []string{"_id"},
	}

	var args *UpdateByIdReq
	err := gconv.Struct(req, &args)
	if err != nil {
		panic(err)
	}
	fmt.Printf("%T", args.Doc["craft"])
}

type UpdateByIdReq struct {
	Id     string                 `json:"id" v:"required|length:24,24#id长度错误"`
	Doc    map[string]interface{} `json:"doc" v:"required"`
	Fields []string               `json:"fields"`
}

What did you see happen?

输出 *interface {}

What did you expect to see?

应该是 interface{}

aundis avatar Aug 15 '24 06:08 aundis

package main

import (
	"fmt"

	"github.com/gogf/gf/v2/util/gconv"
)

func main() {
	dataMap := map[string]any{
		"doc": map[string]any{
			"craft": nil,
		},
	}

	var args *Data
	err := gconv.Struct(dataMap, &args)
	if err != nil {
		panic(err)
	}
	fmt.Printf("args: %T\n", args.Doc["craft"])
	fmt.Printf("dataMap: %T\n", dataMap["doc"].(map[string]any)["craft"])
}

type Data struct {
	Doc map[string]interface{} `json:"doc"`
}

Shouldn't your expected output here be nil?

wlynxg avatar Aug 15 '24 09:08 wlynxg

In Go, when you assign nil to a variable of type interface{}, that variable is actually an interface{} pointer to nil. So, when you try to print ARGS. Doc["craft"], it appears as *interface{}, indicating that the value is nil, and the interface{} type holds a pointer to nil.

AZ000000 avatar Aug 22 '24 08:08 AZ000000

func main() {
	req := map[string]any{
		"id": "123",
		"doc": map[string]any{
			"craft": nil,
		},
		"fields": []string{"_id"},
	}

	var args *UpdateByIdReq
	err := gconv.Struct(req, &args)
	if err != nil {
		panic(err)
	}
	var abc interface{}
	abc = nil
	fmt.Printf("%T, %T", args.Doc["craft"], abc)
}

output

 *interface {}, <nil>

If I check args.Doc["craft"] == nil here, it returns false. Isn't this counterintuitive?

aundis avatar Aug 22 '24 09:08 aundis

You should expect the output to be <nil>, right?

wlynxg avatar Aug 22 '24 09:08 wlynxg

您应该期望输出是 ,对吧?<nil>

yes

aundis avatar Aug 22 '24 09:08 aundis

Bot detected the issue body's language is not English, translate it automatically. 👯👭🏻🧑‍🤝‍🧑👫🧑🏿‍🤝‍🧑🏻👩🏾‍🤝‍👨🏿👬🏿


You should expect the output to be , right? <nil>

yes

Issues-translate-bot avatar Aug 22 '24 09:08 Issues-translate-bot

my fix should be correct

wlynxg avatar Aug 22 '24 09:08 wlynxg

my fix should be correct

Is this a bug?

aundis avatar Aug 22 '24 09:08 aundis

yes

wlynxg avatar Aug 22 '24 09:08 wlynxg

In Go, when you assign nil to a variable of type interface{}, that variable is actually an interface{} pointer to nil. So, when you try to print ARGS. Doc["craft"], it appears as *interface{}, indicating that the value is nil, and the interface{} type holds a pointer to nil.

Thank you. My expected type is <nil>, so that it's easier to make subsequent checks, such as value == nil.

aundis avatar Aug 22 '24 09:08 aundis

yes

Thank you

aundis avatar Aug 22 '24 09:08 aundis