英文:
Golang create struct in different way
问题
大家好!我是Go语言的初学者。在学习reflect
包时,我有一些疑问。以下是代码:
package main
import (
"encoding/json"
"fmt"
"reflect"
)
func checkError(err error) {
if err != nil {
panic(err)
}
}
type Test struct {
X int
Y string
}
func main() {
fmt.Println("hello world!")
test1()
test2()
}
func test1() {
a := Test{}
fmt.Printf("a: %v %T \n", a, a)
fmt.Println(a)
err := json.Unmarshal([]byte(`{"X":1,"Y":"x"}`), &a)
checkError(err)
fmt.Printf("a: %v %T \n", a, a)
}
func test2() {
fmt.Println("===========================")
m := make(map[string]reflect.Type)
m["test"] = reflect.TypeOf(Test{})
a := reflect.New(m["test"]).Elem().Interface()
fmt.Printf("a: %v %T \n", a, a)
fmt.Println(a)
err := json.Unmarshal([]byte(`{"X":1,"Y":"x"}`), &a)
checkError(err)
fmt.Printf("a: %v %T \n", a, a)
}
结果如下:
a: {0 } main.Test
{0 }
a: {1 x} main.Test
===========================
a: {0 } main.Test
{0 }
a: map[X:1 Y:x] map[string]interface {}
为什么这两种方式会产生不同的结果?有人能告诉我原因吗?非常感谢。
英文:
guys! I am a beginner in Go. I have some doubts When I learning reflect
package ,here's the code:
package main
import (
"encoding/json"
"fmt"
"reflect"
)
func checkError(err error) {
if err != nil {
panic(err)
}
}
type Test struct {
X int
Y string
}
func main() {
fmt.Println("hello world!")
test1()
test2()
}
func test1() {
a := Test{}
fmt.Printf("a: %v %T \n", a, a)
fmt.Println(a)
err := json.Unmarshal([]byte(`{"X":1,"Y":"x"}`), &a)
checkError(err)
fmt.Printf("a: %v %T \n", a, a)
}
func test2() {
fmt.Println("===========================")
m := make(map[string]reflect.Type)
m["test"] = reflect.TypeOf(Test{})
a := reflect.New(m["test"]).Elem().Interface()
fmt.Printf("a: %v %T \n", a, a)
fmt.Println(a)
err := json.Unmarshal([]byte(`{"X":1,"Y":"x"}`), &a)
checkError(err)
fmt.Printf("a: %v %T \n", a, a)
}
and the result :
a: {0 } main.Test
{0 }
a: {1 x} main.Test
===========================
a: {0 } main.Test
{0 }
a: map[X:1 Y:x] map[string]interface {}
Why these two way make different result, Could anyone tell me why, many thanks.
答案1
得分: 2
在test2
中,您传递了包含Test
值的interface{}
的地址。当json包解引用该值时,它只看到一个interface{}
,因此将其解组为默认类型。
您需要的是一个包含指向Test
值的指针的interface{}
。
// reflect.New正在创建一个*Test{}值。
// 您不想使用Elem()解引用它。
a := reflect.New(m["test"]).Interface()
// 'a'包含一个*Test值。您已经有一个指针,而且您不想要接口值的地址。
err := json.Unmarshal([]byte(`{"X":1,"Y":"x"}`), a)
英文:
In test2
you're passing in the address of the interface{}
containing a Test
value. When the value is dereferenced by the json package it only sees an interface{}
, and therefor it unmarshals into the default types.
What you need is an interface{}
containing a pointer to a Test
value.
// reflect.New is creating a *Test{} value.
// You don't want to dereference that with Elem()
a := reflect.New(m["test"]).Interface()
// 'a' contains a *Test value. You already have a pointer, and you
// don't want the address of the interface value.
err := json.Unmarshal([]byte(`{"X":1,"Y":"x"}`), a)
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论