Go – 解析 JSON 时出现奇怪的连字符错误

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

Go - strange json hyphen unmarshall error

问题

我在处理一个JSON字符串时遇到了一个非常奇怪的错误。问题首次出现是当我向JSON输入添加了一个字符串键值对时,即"DeviceIdentifier": "device-id"。我将代码简化到最小,以显示错误。当我改变该键值对中的数据的几乎任何内容时,错误就消失了,这对我来说似乎非常奇怪。我可以使用其他键来避免错误,但似乎我在这里漏掉了什么。要么是我漏掉了什么,要么是库函数有问题...有什么想法吗?

package main

import (
	"encoding/json"
	"fmt"
)

type S struct {
	Name            string
	DeviceIdentifier []byte
}

func main() {
	var s S

	data := []byte(`{"Name": "test", "DeviceIdentifier": "device-id"}`)

	if err := json.Unmarshal(data, &s); err != nil {
		fmt.Println(err.Error())
	}
}

Go Playground链接:http://play.golang.org/p/huXuaokGik

JSON包文档:http://golang.org/pkg/encoding/json/

更新

我刚刚发现,当值字符串的长度可以被4整除时,编码成功,例如abcdabcdefgh可以工作,而abcdeabcdefg则不行。

现在我知道了什么是Base64字符串,错误就有了很多意义。参考资料如下:

维基百科:http://en.wikipedia.org/wiki/Base64

转换工具:http://www.string-functions.com/base64encode.aspx

英文:

I am having a very strange error while working with a json string. The problem was first introduced when I added a key-value pair of strings to the json input, which was "DeviceIdentifier": "device-id". I pared down my code to the minimum necessary to display the error. The error disappears when I change pretty much anything about the data in that key-value pair, which seems very strange to me. I can just use other keys to circumvent the error, but it seems like there is something I am missing here. Either that or there would seem to be something wrong with the library function... Any ideas?

package main

import (
    "encoding/json"
    "fmt"
)

type S struct {
	Name            string
    DeviceIdentifier []byte
}

func main() {
    var s S

	data := []byte(`{"Name": "test", "DeviceIdentifier": "device-id"}`)

	if err := json.Unmarshal(data, &s); err != nil {
		fmt.Println(err.Error())
	}
}

Go playground link: http://play.golang.org/p/huXuaokGik

Json package documentation: http://golang.org/pkg/encoding/json/

UPDATE

I just discovered that the encoding succeeds when the value string has a length that is divisible by 4, e.g. abcd and abcdefgh work, while abcde and abcdefg` do not.

Now that I know what base64 strings are the error makes a lot of sense. References here:

Wikipedia: http://en.wikipedia.org/wiki/Base64

Conversion tool: http://www.string-functions.com/base64encode.aspx

答案1

得分: 2

根据json包文档:

> 数组和切片值编码为JSON数组,除了[]byte编码为base64编码的字符串,nil切片编码为null JSON对象。

所以,如果你将结构更改为DeviceIdentifier string,它将起作用。

Go Playground

英文:

from the json package documentation :

> Array and slice values encode as JSON arrays, except that []byte
> encodes as a base64-encoded string, and a nil slice encodes as the
> null JSON object.

so if you change your structure to DeviceIdentifier string it will work

Go Playground

答案2

得分: 0

只是为了提及另一种可能性,为了保持结构字段为[]byte,也可以在客户端上实际执行base64编码,以便通过json传递的值表示base64中的有效内容。这是我在项目中使用的解决方案。Go中的json.Marshal()函数会自动为包含字节切片的结构执行此操作。

英文:

Just to note another possibility, in order to keep the struct field as a []byte, it also works perfectly well to just actually do the base64 encoding on the client side so that the value passed through the json represents something valid in base64. This was the solution I ended up using in my project. The json.Marshal() function in Go does this automatically for structs that contain a byte slice.

huangapple
  • 本文由 发表于 2015年2月12日 05:19:28
  • 转载请务必保留本文链接:https://go.coder-hub.com/28464711.html
匿名

发表评论

匿名网友

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

确定