### 概述
在go中,结构体想转成json,变量名首字母必须是大写 .
#### 通过结构体生成json
~~~
type Person struct {
Company string //首字母要大写
Subjects []string
IsOk bool
Price float64
}
func main() {
s := Person{"ali", []string{"PHP", "JAVA", "GO"}, true, 1000}
buf, err := json.Marshal(s) //json.MarshalIndent(s,""," ")可以格式化打印
if err != nil {
fmt.Println(err)
return
}
fmt.Println(string(buf))
}
~~~
~~~
{"Company":"ali","Subjects":["PHP","JAVA","GO"],"IsOk":true,"Price":1000}
~~~
### struct_tag使用
~~~
type Person struct {
Company string `json:"company"` //二次编码
Subjects []string `json:"-"` //-代表此字段不会输出到屏幕
IsOk bool `json:",string"` //把bool转换成字符串
Price float64
}
func main() {
s := Person{"ali", []string{"PHP", "JAVA", "GO"}, true, 1000}
buf, err := json.Marshal(s)
if err != nil {
fmt.Println(err)
return
}
fmt.Println(string(buf))
}
~~~
~~~
{"company":"ali","IsOk":"true","Price":1000}
~~~
### 通过map生成json
~~~
m := make(map[string]interface{}, 4)
m["company"] = "facebook"
m["subjects"] = []string{"PHP", "JAVA", "GO"}
m["isok"] = true
m["price"] = 100
res, err := json.MarshalIndent(m, "", " ") //第三个参数是tab
if err != nil {
fmt.Println(err)
return
}
fmt.Println(string(res))
~~~
~~~
{
"company": "facebook",
"isok": true,
"price": 100,
"subjects": [
"PHP",
"JAVA",
"GO"
]
}
~~~
### json解析到结构体
~~~
type Person struct {
Company string
Subjects []string
IsOk bool
Price float64
}
type Person1 struct {
Company string
Subjects []string
}
func main() {
jsonBuf := `{
"company": "facebook",
"isok": true,
"price": 100,
"subjects": [
"PHP",
"JAVA",
"GO"
]
}`
var p Person
err := json.Unmarshal([]byte(jsonBuf), &p) //这里必须是取地址
if err != nil {
fmt.Println(err)
return
}
fmt.Println(p)
fmt.Printf("%+v\n", p)
var p1 Person1
err = json.Unmarshal([]byte(jsonBuf), &p1) //这里必须是取地址
if err != nil {
fmt.Println(err)
return
}
fmt.Println(p1)
fmt.Printf("%+v\n", p1)
}
~~~
~~~
{facebook [PHP JAVA GO] true 100}
{Company:facebook Subjects:[PHP JAVA GO] IsOk:true Price:100}
{facebook [PHP JAVA GO]}
{Company:facebook Subjects:[PHP JAVA GO]}
~~~
### json解析到map
相比于结构体,map要复杂一点,因为要通过类型断言来反推类型.
~~~
func main() {
jsonBuf := `{
"company": "facebook",
"isok": true,
"price": 100,
"subjects": [
"PHP",
"JAVA",
"GO"
]
}`
m := make(map[string]interface{}, 4)
err := json.Unmarshal([]byte(jsonBuf), &m)
if err != nil {
fmt.Println(err)
return
}
//fmt.Printf("%+v", m)
var str string
//str = m["company"] //无法直接赋值,哪怕用string()也不行
//fmt.Println(str)
for key, value := range m {
switch data := value.(type) {
case string:
str = data
fmt.Printf("字符串类型,key = %s,value = %s\n", key, str)
case bool:
fmt.Printf("布尔类型,key = %s,value = %v\n", key, data)
case float64:
fmt.Printf("布尔类型,key = %s,value = %v\n", key, data)
case []interface{}:
//这个要注意
fmt.Printf("切片类型,key = %s,value = %v\n", key, data)
}
}
}
~~~
~~~
布尔类型,key = isok,value = true
布尔类型,key = price,value = 100
切片类型,key = subjects,value = [PHP JAVA GO]
字符串类型,key = company,value = facebook
~~~
### 自定义struct转json
实现以下两个接口即可
~~~
type Marshaler interface {
MarshalJSON() ([]byte, error)
}
type Unmarshaler interface {
UnmarshalJSON([]byte) error
}
~~~
- 基本语法
- 申明变量
- 常量
- 数据类型
- 强制类型转换
- 获取命令行参数
- 指针
- 概述
- new函数
- 函数
- 概述
- 不定参数类型
- 有返回值
- 函数类型
- 回调函数
- 匿名函数和闭包
- 延迟调用defer
- 工程管理
- 工作区
- src,pkg和bin目录
- 复合类型
- 概述
- 数组
- 概述
- 声明并初始化
- 拷贝传值
- slice
- 概述
- 创建切片
- 切片截取
- 切片和底层数组的关系
- slice常用方法
- 切片做函数参数
- map
- 概述
- map操作
- 结构体
- 概述
- 结构体初始化
- 结构体比较
- 结构体作为函数参数
- 结构体前加&
- 面向对象
- 概述
- 匿名组合
- 方法
- 值语义和引用语义
- 方法集
- 方法的继承
- 方法重写
- 方法值
- 接口
- 接口定义和实现
- 多态的表现
- 接口继承
- 接口转换
- 空接口
- 类型断言
- 异常处理
- error接口
- panic
- recover
- 文本文件处理
- 字符串操作
- 正则表达式
- json处理
- 文件操作
- 标准设备文件操作
- 并发编程
- 概述
- 并发和并行
- go语言并发优势
- goroutine
- goroutine概述
- 创建goroutine
- 主协程先退出
- runtime包
- Gosched
- Goexit
- GOMAXPROCE
- channel
- 多资源竞争
- channel类型
- 无缓冲channel
- 有缓冲channel
- 关闭channel
- 单向channel
- 单向channel特性
- 定时器
- Timer
- Ticker
- select
- select作用
- 超时
- sync
- 竞争状态
- 网络编程
- 网络概述
- 网络协议
- 分层模型
- 网络分层架构
- 层与协议
- 每层协议的功能
- 链路层
- 网络层
- 传输层
- 应用层
- socket编程
- 组合和继承
- 注意事项
- 细节
- go语言实现队列
- google工程师golang
- 基础语法
- 内建容器
- 面向"对象"
- 依赖管理
- 面向接口
- 函数式编程
- 错误处理和资源管理
- 测试与性能调优
- goroutine
- channel
- golang问题集
- 断言和类型转换
- Go语言圣经
- 入门
- 程序结构
- 命名
- 声明
- 变量
- 赋值
- 类型
- 包和文件
- 作用域
- 基础数据类型
- 整数
- 浮点数
- 复数
- 布尔型
- 字符串
- 常量
- 复合数据类型
- 数组
- slice
- map
- 结构体
- json
- 文本和HTML模板
- 函数
- 函数声明
- 错误
- 函数值
- 匿名函数
- defer
- panic
- recover
- 方法
- 方法声明
- 指针对象的方法
- 封装
- 接口
- 说明
- 接口是合约
- 实现接口的条件
- 接口值
- 类型断言
- 通过类型断言询问行为
- 类型开关
- Goroutines和Channels
- 协程
- channels
- 无缓冲channel
- 串联的channel
- 有缓冲channel
- 并发的循环
- select多路复用
- 并发的退出
- 并发问题的自我思考
- 基于共享变量的并发
- 竞争条件
- 互斥锁
- 读写锁
- 内存同步
- sync.Once
- 协程和线程
- 包和工具
- 测试
- 反射
- 什么是反射
- 为什么需要反射
- reflect.Type和reflect.Value
- 通过reflect.Value修改值
- 底层编程
