Go的json.Unmarshal在处理json.RawMessage类型定义时无法正常工作。

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

Go json.Unmarshal does not work with type definition of json.RawMessage

问题

我有一个类似这样的小型Go程序:

package main

import "encoding/json"

func main() {
	bs := []byte(`{"items": ["foo", "bar"]}`)

	data := Data{}
	err := json.Unmarshal(bs, &data)
	if err != nil {
		panic(err)
	}
}

type Data struct {
	Items []Raw `json:"items"`
}

// 如果我这样做,程序会出现"illegal base64 data at input byte 0"的错误
type Raw json.RawMessage

// 这样就可以正常工作
type Raw = json.RawMessage

为什么json.Unmarshal可以使用类型别名而不是类型定义?这个错误消息是什么意思?

英文:

I have a small Go program like this:

package main

import "encoding/json"

func main() {
	bs := []byte(`{"items": ["foo", "bar"]}`)

	data := Data{}
	err := json.Unmarshal(bs, &data)
	if err != nil {
		panic(err)
	}
}

type Data struct {
	Items []Raw `json:"items"`
}

// If I do this, this program panics with "illegal base64 data at input byte 0"
type Raw json.RawMessage

// This works
type Raw = json.RawMessage

Why does json.Unmarshal work with type alias but not type definition? What does that error message mean?

答案1

得分: 3

这是一个新的类型定义:

type Raw json.RawMessage

Raw 类型派生自 json.RawMessage,但它是一个全新的类型,没有定义 json.RawMessage 的任何方法。因此,如果 json.RawMessage 有一个 JSON 反序列化方法,Raw 类型就没有这个方法。以下代码将无法将类型为 Raw 的变量 t 识别为 json.RawMessage

if t, ok := item.(json.RawMessage); ok {
  ...
}

这是一个类型别名:

type Raw = json.RawMessage

在这里,Raw 拥有 json.RawMessage 的所有方法,可以进行类型断言为 json.RawMessage,因为 Raw 只是 json.RawMessage 的另一个名称。

英文:

This is a new type definition:

type Raw json.RawMessage

The Raw type is derived from json.RawMessage, but it is a new type without any of the methods defined for json.RawMessage. So, if json.RawMessage has a json unmarshaler method, Raw does not have that. Code such as following will not recognize a variable t of type Raw as a json.RawMessage:

if t, ok:=item.(json.RawMessage); ok {
  ...
}

This is a type alias:

type Raw = json.RawMessage

Here, Raw has all the methods json.RawMessage has, and type assertion to json.RawMessage will work, because Raw is simply another name for json.RawMessage.

huangapple
  • 本文由 发表于 2022年2月9日 07:35:47
  • 转载请务必保留本文链接:https://go.coder-hub.com/71042268.html
匿名

发表评论

匿名网友

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

确定