英文:
How golang handle pointer in this JSON unmarshal example?
问题
反序列化JSON时,我发现我们需要传递一个输出地址来检索结果,但出于某种原因,我更喜欢传统地检索结果。
这里有一个例子:https://play.golang.org/p/3hN1iLrDPGv
package main
import (
"encoding/json"
"fmt"
"time"
)
type FruitBasket struct {
Name string
Fruit []string
Id int64 `json:"ref"`
private string // 未导出的字段不会被编码。
Created time.Time
}
type FruitBaskets []FruitBasket
func Deserialize(val interface{}) interface{} {
serialBytes := `[{"Name":"Standard2","Fruit":["Apple","Banana","Orange"],"ref":999,"private":"Second-rate","Created":"2021-08-13T11:55:12.541568+07:00"}]`
err := json.Unmarshal([]byte(serialBytes), &val)
if err != nil {
fmt.Printf("err: %s", err)
}
return val
}
func main() {
out1 := Deserialize(&FruitBaskets{})
// out2 := out1.(FruitBaskets) // 我想要这行
out2 := out1.(*FruitBaskets)
fmt.Println("Testing and got..", out2)
}
英文:
To deserialize JSON I found that we need to pass an output address to retrieve the result but for some reason I prefer to retrieve the result traditionally.
Here an example: https://play.golang.org/p/3hN1iLrDPGv
package main
import (
"encoding/json"
"fmt"
"time"
)
type FruitBasket struct {
Name string
Fruit []string
Id int64 `json:"ref"`
private string // An unexported field is not encoded.
Created time.Time
}
type FruitBaskets []FruitBasket
func Deserialize(val interface{}) interface{} {
serialBytes := `[{"Name":"Standard2","Fruit":["Apple","Banana","Orange"],"ref":999,"𒀸private":"Second-rate","Created":"2021-08-13T11:55:12.541568+07:00"}]`
err := json.Unmarshal([]byte(serialBytes),&val)
if err != nil {
fmt.Printf("err: %s", err)
}
return val
}
func main() {
out1 := Deserialize(&FruitBaskets{})
// out2 := out1.(FruitBaskets) // I want this line
out2 := out1.(*FruitBaskets)
fmt.Println("Testing and got..",out2)
}
答案1
得分: 2
stdlib JSON编组器始终需要一个指向结构体的指针来进行解组。如果你尝试传入一个非指针的值,将返回一个json.InvalidUnmarshalError
错误。
看起来你正在尝试编写一个只返回值的方法。为了实现这个目的,你需要为每种类型创建一个Deserialize()
函数,该函数返回特定的类型。例如:
func Deserialize(in []byte) (FruitBasket, error) {
fb := &FruitBasket{}
err := json.Unmarshal(in, &fb)
if err != nil {
fmt.Printf("err: %s", err)
return FruitBasket{}, err
}
return *fb, nil
}
一旦泛型被引入到Go语言中,就可以编写适用于所有类型的函数。但在当前系统的限制下,这是不可能的。
英文:
The stdlib JSON marshaller will always require a pointer to a struct to unmarshal into. If you attempt to pass in a value that is not a pointer, then a json.InvalidUnmarshalError
will be returned.
It appears you are trying to write a method that will just return a value. In order to do this, you will need to create a Deserialize()
function for each of your types, that return that specific type. For example:
func Deserialize(in []byte) (FruitBasket, error) {
fb := &FruitBasket{}
err := json.Unmarshal(in, &fb)
if err != nil {
fmt.Printf("err: %s", err)
return FruitBasket{}, err
}
return *fb, nil
}
Once Generics have been introduced to Go, it will be possible to write a function that works for all types. But under the current constraints of the system it is not possible.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论