在項目中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成功,時而失敗,所以才定位了一下,記錄在此。