工作中经常需要在使用数据前,将其格式进行相应的转换。常见的操作有

  • 字符串与数字之间的相互转换
  • 字节码byte与字符串之间的相互转换
  • 映射map与json之间的转换 (内置库实现)
  • 结构体struct与json格式之间的转换 (内置库实现)
  • 映射map与结构体struct之间的相互转换

字符串与数字之间的转换

package main

import (
"fmt"
"reflect"
"strconv"
)

func main() {
var num int = 5
fmt.Println("当前变量的< num >类型是: ", reflect.TypeOf(num))

new_num := strconv.Itoa(num)
fmt.Println("当前转换后变量的< num >类型是: ", reflect.TypeOf(new_num))

var str string = "100"
fmt.Println("当前变量的< str >类型是: ", reflect.TypeOf(str))

new_str, err := strconv.Atoi(str)
if err != nil {
fmt.Println("类型转换失败")
}
fmt.Println("当前转换后变量的< str >类型是: ", reflect.TypeOf(new_str))

}

运行结果

% go run main.go
当前变量的< num >类型是: int
当前转换后变量的< num >类型是: string
当前变量的< str >类型是: string
当前转换后变量的< str >类型是: int


字节码与字符串转换

package main

import (
"fmt"
)

func main() {
var a string = "I am string"
fmt.Println("原始字符串: ", a)
MyByteSlice := []byte(a)
fmt.Println("字符串->字节组: ", MyByteSlice)

MyString := string(MyByteSlice)
fmt.Println("字节组->字符串: ", MyString)
}

运行结果

% go run main.go
原始字符串: I am string
字符串->字节组: [73 32 97 109 32 115 116 114 105 110 103]
字节组->字符串: I am string


映射map与json之间的互转

json -> map

package main

import (
"encoding/json"
"fmt"
"reflect"
)

func main() {
JsonStr := "{\"name\":\"wgw\",\"age\":18,\"personInfo\":{\"addr\":\"china\",\"job\":\"it\"}}"
// 创建一个空的map,value的数据类型是空接口
DataMap := make(map[string]interface{})

// 使用内置的json库解析JsonStr
//两个参数: 一个必须是字节码格式,一个必须是指针地址
if err := json.Unmarshal([]byte(JsonStr), &DataMap); err != nil {
// 只返回一个错误状态,
fmt.Printf("Json格式转换失败: %s \n", err)
}

for key, val := range DataMap {
fmt.Printf("key的类型: %v, value的类型: %v \n", reflect.TypeOf(key), reflect.TypeOf(val))
fmt.Printf("key的值: %v, value的值: %v \n", key, val)
fmt.Printf("--------\n")
}

// 根据反射的数据类型为空接口数据断言
if age, ok := DataMap["age"].(float64); !ok {
fmt.Printf("空接口类型转换为< %s >失败 \n", reflect.TypeOf(DataMap["age"]))
} else {
// 先断言为float64 再转换为
fmt.Printf("年龄: %d\n", int(age))
}

personInfo := DataMap["personInfo"].(map[string]interface{})
fmt.Printf("地址: %s\n", personInfo["addr"].(string))

}

运行结果

% go run main.go
key的类型: string, value的类型: string
key的值: name, value的值: wgw
--------
key的类型: string, value的类型: float64 // json中的数字转换后数据格式为float6
key的值: age, value的值: 18
--------
key的类型: string, value的类型: map[string]interface {}
key的值: personInfo, value的值: map[addr:china job:it]
--------
年龄: 18
地址: china

map -> json

package main

import (
"encoding/json"
"fmt"
)

func main() {
// 定义一个空接口为值的map
MyMap := make(map[string]interface{})

// 写入嵌套map类型的数据
MyMap["Name"] = "wgw"
MyMap["age"] = 18
MyMap["Info"] = map[string]interface{}{
"addr": "china",
"Id": 1234,
}

// Marshal的返回值是一个字节组
JsonByte, err := json.Marshal(&MyMap)
if err != nil {
fmt.Println(err)
}
// byte转换为string后打印
fmt.Println(string(JsonByte))
}

运行结果

% go run main.go
{"Info":{"Id":1234,"addr":"china"},"Name":"wgw","age":18}


结构体struct与json格式之间转换

json -> struct

struct 与 map 都可以用来存储KV结构的数据。但是结构体重中的字段需要提前定义好,不存在随意增减修改字段的操作,也就不会有使用interface{}接收数据的场景。

package main

import (
"encoding/json"
"fmt"
)

func main() {
JsonStr := "{\"Info\":{\"Id\":1234,\"addr\":\"china\"},\"Name\":\"wgw\",\"age\":18}"

// 根据json字符串的结构,定义对应的结构体

type SubInfo struct {
// 结构体的中的字段名与json中字段名的对应关系
Id int `json:"Id"`
Addr string `json:"addr"`
}

type JsonData struct {
Name string `json:"Name"`
Age int `json:"age"`
Info SubInfo // 结构体嵌套
}

var data JsonData

if err := json.Unmarshal([]byte(JsonStr), &data); err != nil {
fmt.Println("Json To Struct Failed")
} else {
fmt.Printf("Age的值为< %d >,数据类型为< %T >\n", data.Age, data.Age)
fmt.Printf("Id的值为< %d >,数据类型为< %T >\n", data.Info.Id, data.Info.Id)

x := 1
// 结构体的字段,取出即可进行运算
x = x + data.Age
fmt.Println("Age相加的结果为: ", x)
}
}

运行结果

% go run main.go
Age的值为< 18 >,数据类型为< int >
Id的值为< 1234 >,数据类型为< int >
Age相加的结果为: 19

struct -> json

package main

import (
"encoding/json"
"fmt"
)

func main() {
type SubInfo struct {
// 结构体的中的字段名与json中字段名的对应关系
Id int `json:"Id"`
Addr string `json:"addr"`
}

type JsonData struct {
Name string `json:"Name"`
Age int `json:"age"`
Info []SubInfo // slice中的数据类型是结构体
}

// 实例化要转换为Json的结构体
data := JsonData{
Name: "wgw",
Age: 18,
Info: []SubInfo{
{Id: 123, Addr: "china"},
{Id: 456, Addr: "USA"},
},
}

// 将struct序列化为json字节组
if JsonByte, err := json.Marshal(&data); err != nil {
fmt.Println("Struct To Json Failed")
} else {
fmt.Println(string(JsonByte))
}
}

运行结果

% go run main.go
{"Name":"wgw","age":18,"Info":[{"Id":123,"addr":"china"},{"Id":456,"addr":"USA"}]}


映射map与结构体struct之间的转换

这里就不演示代码了,只说一下思路,把上面的步骤结合一下通过json格式中转即可

map <---> JsonStr <---> struct