在项目中golang处理string时遇到 string json.unmarshal 失败问题,在此记录一下:
package main
import "encoding/json"
import "fmt"
func main() {
str := "golang"
// test 1
strA, _ := json.Marshal(str) // strA len:8, cap: 8
fmt.Println(strA) // [34 103 111 108 97 110 103 34]
resA := new(string)
//1、unmarshal 通过 marshal之后的 字符串是没有问题的
err := json.Unmarshal(strA, &resA)
if err != nil {
fmt.Println(err) // golang
}
fmt.Println(*resA)
// test 2
strB := []byte(str) // strB len: 6, cap: 8
fmt.Println(strB) // [103 111 108 97 110 103]
resB := new(string)
//2、unmarshal 通过[]byte 强制转换后的字符串有问题,为什么呢?
errB := json.Unmarshal(strB, &resB)
if errB != nil {
fmt.Println(errB) // invalid character 'g' looking for beginning of value
}
fmt.Println(*resB)
}
字符串通过[]byte强制转换后 unmarshal,就会出error,通过err 信息可以看出 g 字符在开头,此时注意看注释中 strA 和 strB 的长度len,还有打印的byte信息,strB 长度少2,前后少了ASCII 34 ,查表得知ASCII 34 刚好是 引号!! 原来强转之后只剩内里了,首字符变为g了,unmarshal 时会在函数 stateBeginValue 中检查首字符,不在范围内所以就err了。
那么问题来了,怎样才能让强转之后的字符串也可以unmarshal呢?
把少的前后字符加上啊。
package main
import (
"encoding/json"
"strconv"
)
import "fmt"
func main() {
str := "golang"
// test 1
strA, _ := json.Marshal(str) // strA len:8, cap: 8
fmt.Println(strA) // [34 103 111 108 97 110 103 34]
resA := new(string)
//1、unmarshal 通过 marshal之后的 字符串是没有问题的
err := json.Unmarshal(strA, &resA)
if err != nil {
fmt.Println(err) // golang
}
fmt.Println(*resA)
// test 2
strB := []byte(str) // strB len: 6, cap: 8
fmt.Println(strB) // [103 111 108 97 110 103]
resB := new(string)
//2、unmarshal 通过[]byte 强制转换后的字符串有问题,为什么呢?
errB := json.Unmarshal(strB, &resB)
if errB != nil {
fmt.Println(errB) // invalid character 'g' looking for beginning of value
}
fmt.Println(*resB)
// test 3
// 三种添加引号的方式
//str3 := `"goalng"`
//str3 := "\"goalng\""
str3 := strconv.Quote("golang")
strC := []byte(str3) // strB len: 8, cap: 8
fmt.Println(strC) // [34 103 111 108 97 110 103 34]
resC := new(string)
errC := json.Unmarshal(strC, &resC)
if errC != nil {
fmt.Println(errC)
}
fmt.Println(*resC) // golang
}
其实呢,也不可能为了unmarshal 字符串,而去绕一圈,最后还是得到字符串,我这是在项目中与调用第三方API时,调试过程中遇到返回的数据不稳定,时而unmarshal成功,时而失败,所以才定位了一下,记录在此。