在这个JSON解组示例中,Golang如何处理指针?

huangapple go评论88阅读模式
英文:

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.

huangapple
  • 本文由 发表于 2021年8月16日 17:40:52
  • 转载请务必保留本文链接:https://go.coder-hub.com/68800550.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定