golang json 使用
2022-03-28 00:00 youxin 阅读(561) 评论(0) 编辑 收藏 举报golang关于json库的一个比较容易陷入的坑 uint8[]数组的json转换问题.
类似这个CA如果实例转化成json.List会变成字符串.
type CA struct {
List []uint8
}
func main() {
ca := CA{[]uint8{1,2,3,4,5,6,7,8,9,0}}
r, _ := json.Marshal(ca)
fmt.Println(string(r)) //{"List":"AQIDBAUGBwgJAA=="}
}
而我们希望的是要一个正常的json. 只有 int8 byte uint8 这种8位的json库会给我们当成字符串处理.想要解决.如果拍脑袋就不能用这几种类型了.需要使用16 32 64位的数字才可以正常转换成json字符串.
{"List":[1,2,3,4,5,6,7,8,9,0]}
但是不用担心. Unmarshal这个 我们认为不想要的json字符串 重新到CA的其他实例 会得到想要的结果.
.如果是跨语言的json通信就要小心了.
————————————————
原文链接:https://blog.csdn.net/spiritring/article/details/11570219
对于不知道类型的多源数据流的解码通常这样:
采用标准的encoding/json库将数据解码为通用map[string]interface{}类型
利用mapstructure库转为相应的 Go 结构体
package main import ( "encoding/json" "fmt" "log" "github.com/mitchellh/mapstructure" ) type Person struct { Name string Age int Job string } type Cat struct { Name string Age int Breed string } func (c *Cat) miao(){ fmt.Println("喵喵喵~") } func main() { datas := []string{ `{ "type": "person", "name":"dj", "age":18, "job": "programmer" }`, `{ "type": "cat", "name": "kitty", "age": 1, "breed": "Ragdoll" }`, } for _, data := range datas { var m map[string]interface{} err := json.Unmarshal([]byte(data), &m) //转到通用接口中 if err != nil { log.Fatal(err) } fmt.Println(m["type"]) //输出 person fmt.Println(m) //输出 map[age:18 job:programmer name:dj type:person] switch m["type"].(string) { //获取key-value,接口类型转为字符出(断言) case "person": var p Person mapstructure.Decode(m, &p) //转为结构体 fmt.Println("person", p) //输出 person {dj 18 programmer} case "cat": var cat Cat mapstructure.Decode(m, &cat) fmt.Println("cat", cat) cat.miao() } } }
map1 := make(map[string]interface{}) map1["1"] = "hello" map1["2"] = "world" //return []byte str, err := json.Marshal(map1) if err != nil { fmt.Println(err) } fmt.Println("map to json", string(str)) //json([]byte) to map map2 := make(map[string]interface{}) err = json.Unmarshal(str, &map2) if err != nil { fmt.Println(err) }
https://blog.csdn.net/wowenlong/article/details/113571853
https://blog.csdn.net/xz_studying/article/details/109278619
Go按照RFC 4627的标准实现了一个json编解码的标准库
func Unmarshal(data []byte, v interface{}) error
Unmarshal用于反序列化json的函数 根据data将数据反序列化到传入的对象中
仔细查看代码中的四种情况
1 将json反序列化成struct对象
2 将json反序列化到可以存储struct的slice中
3 将json 反序列化到map中
4 将json反序列化到slice中
package main
import (
"encoding/json"
"fmt"
)
func main() {
type Person struct {
Name string
Age int
Gender bool
}
//unmarshal to struct
var p Person
var str = `{"Name":"junbin", "Age":21, "Gender":true}`
json.Unmarshal([]byte(str), &p)
//result --> junbin : 21 : true
fmt.Println(p.Name, ":", p.Age, ":", p.Gender)
// unmarshal to slice-struct
var ps []Person
var aJson = `[{"Name":"junbin", "Age":21, "Gender":true},
{"Name":"junbin", "Age":21, "Gender":true}]`
json.Unmarshal([]byte(aJson), &ps)
//result --> [{junbin 21 true} {junbin 21 true}] len is 2
fmt.Println(ps, "len is", len(ps))
// unmarshal to map[string]interface{}
var obj interface{} // var obj map[string]interface{}
json.Unmarshal([]byte(str), &obj)
m := obj.(map[string]interface{})
//result --> junbin : 21 : true
fmt.Println(m["Name"], ":", m["Age"], ":", m["Gender"])
//unmarshal to slice
var strs string = `["Go", "Java", "C", "Php"]`
var aStr []string
json.Unmarshal([]byte(strs), &aStr)
//result --> [Go Java C Php] len is 4
fmt.Println(aStr, " len is", len(aStr))
}
func Marshal(v interface{}) ([]byte, error)
Marshal 用于将struct对象序列化到json对象中
下面这个例子讲解了以下几个例子
1 给field指定别名
2 序列化时忽略字段
3 序列化时忽略值为zero value的字段
4 序列化时 将int类型的值 转换成string
5 slice序列化为json
6 map序列化为json
package main
import (
"encoding/json"
"fmt"
)
//tag中的第一个参数是用来指定别名
//比如Name 指定别名为 username `json:"username"`
//如果不想指定别名但是想指定其他参数用逗号来分隔
//omitempty 指定到一个field时
//如果在赋值时对该属性赋值 或者 对该属性赋值为 zero value
//那么将Person序列化成json时会忽略该字段
//- 指定到一个field时
//无论有没有值将Person序列化成json时都会忽略该字段
//string 指定到一个field时
//比如Person中的Count为int类型 如果没有任何指定在序列化
//到json之后也是int 比如这个样子 "Count":0
//但是如果指定了string之后序列化之后也是string类型的
//那么就是这个样子"Count":"0"
type Person struct {
Name string `json:"username"`
Age int
Gender bool `json:",omitempty"`
Profile string
OmitContent string `json:"-"`
Count int `json:",string"`
}
func main() {
var p *Person = &Person{
Name: "brainwu",
Age: 21,
Gender: true,
Profile: "I am Wujunbin",
OmitContent: "OmitConent",
}
if bs, err := json.Marshal(&p); err != nil {
panic(err)
} else {
//result --> {"username":"brainwu","Age":21,"Gender":true,"Profile":"I am Wujunbin","Count":"0"}
fmt.Println(string(bs))
}
var p2 *Person = &Person{
Name: "brainwu",
Age: 21,
Profile: "I am Wujunbin",
OmitContent: "OmitConent",
}
if bs, err := json.Marshal(&p2); err != nil {
panic(err)
} else {
//result --> {"username":"brainwu","Age":21,"Profile":"I am Wujunbin","Count":"0"}
fmt.Println(string(bs))
}
// slice 序列化为json
var aStr []string = []string{"Go", "Java", "Python", "Android"}
if bs, err := json.Marshal(aStr); err != nil {
panic(err)
} else {
//result --> ["Go","Java","Python","Android"]
fmt.Println(string(bs))
}
//map 序列化为json
var m map[string]string = make(map[string]string)
m["Go"] = "No.1"
m["Java"] = "No.2"
m["C"] = "No.3"
if bs, err := json.Marshal(m); err != nil {
panic(err)
} else {
//result --> {"C":"No.3","Go":"No.1","Java":"No.2"}
fmt.Println(string(bs))
}
}
————————————————
版权声明:本文为CSDN博主「Iconoclast_wu」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/u012807459/article/details/38962439
https://www.cnblogs.com/haiguixiansheng/articles/10718531.html
package main import ( "encoding/json" "fmt" ) func main() { type StuRead struct { Name interface{} `json:"name"` Age interface{} HIgh interface{} sex interface{} Class interface{} `json:"class"` Test interface{} } //方式1:只声明,不分配内存 var stus1 []*StuRead //方式2:分配初始值为0的内存 stus2 := make([]*StuRead,0) //错误示范 //new()只能实例化一个struct对象,而[]StuRead是切片,不是对象 stus := new([]StuRead) stu1 := &StuRead{"asd1",1,1,1,1,1} stu2 := &StuRead{"asd2",2,2,2,2,2} //由方式1和2创建的切片,都能成功追加数据 //方式2最好分配0长度,append时会自动增长。反之指定初始长度,长度不够时不会自动增长,导致数据丢失 stus1 = append(stus1,stu1) //因为上面stus1是切片类型的结构体指针类型,所以append的类型也必须是取的地址。 stus2 = append(stus2,stu2) //因为上面stus2是切片类型的结构体指针类型,所以append的类型也必须是取的地址。 //成功编码 json1,_ := json.Marshal(stus1) json2,_ := json.Marshal(stus2) fmt.Println(string(json1)) fmt.Println(string(json2)) } //打印效果 [{"name":"asd1","Age":1,"HIgh":1,"class":1,"Test":1}] [{"name":"asd2","Age":2,"HIgh":2,"class":2,"Test":2}]
嵌套数据结构
https://blog.csdn.net/zhengzizhi/article/details/74078620
Golang 使用 JSON unmarshal 数字到 interface{} 数字变成 float64 类型
碰到这个问题一脸疑惑,后来不断谷歌才找到答案,小白用户献上解析如下:
这是由于 JSON 里的数字默认都会转成 Golang 的 float64 类型引起的,
使用 Golang 解析 JSON 格式数据时,若以 interface{} 接收数据,则会按照下列规则进行解析:
bool, for JSON booleans
float64, for JSON numbers
string, for JSON strings
[]interface{}, for JSON arrays
map[string]interface{}, for JSON objects
nil for JSON null
而浮点数打印时的默认规则是超过一定长度后会换成科学计数法打印。
因此,只要在打印时指定打印格式,或者(按照LZ示例里是整数的情况时),转换为整数打印
fmt.Println( int( a["id"].(float64) ) ) // 将 “id” 键申明为 float64 类型,再转换为 int 型
一句话总结:所有JSON数值类型一律解析为float64类型,需手动转换;对于map类型需判断是否为nil再转换为所需类型。
interface{}类型在json.Unmarshal时,会自动将JSON转换为对应的数据类型:
JSON的boolean 转换为bool
JSON的数值 转换为float64
JSON的字符串 转换为string
JSON的Array 转换为[]interface{}
JSON的Object 转换为map[string]interface{},也可以转为本身类型
JSON的null 转换为nil
golang map转json的顺序问题
我们都知道map是无序的,每次取出key/value的顺序都可能不一致,但map转json的顺序是不是也是无序的吗?尽管json中的参数顺序大部分情况下对使用没有影响,我们不妨看看源码中怎么处理的。
先说结论:
map转json是有序的,按照ASCII码升序排列key。
https://www.cnblogs.com/jiftle/p/14959834.html
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具
2021-03-28 Cannot assign requested address
2016-03-28 j2ee ehcache
2016-03-28 j2ee servlet listener
2016-03-28 j2ee Servlet、Filter、Listener
2016-03-28 java Servlet中的过滤器Filter