golang json.unmarshal string

golang 专栏收录该内容
0 篇文章 0 订阅

在项目中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成功,时而失败,所以才定位了一下,记录在此。

 

  • 0
    点赞
  • 0
    评论
  • 0
    收藏
  • 一键三连
    一键三连
  • 扫一扫,分享海报

©️2021 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值