golang json.unmarshal string

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

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章