struct_tag的使用
在上面的例子看到,我们根据结构体生成的json的key都是大写的,因为结构体名字在go语言中不大写的话,又没有访问权限,这种问题会影响到我们对json的key的名字,所以go官方给出了struct_tag的方法去修改生成json时,对应key的名字
package main import ( "encoding/json" "fmt" ) //成员变量名首字母必须大写 type IT struct { //Company string `json:"-"` //此字段不会输出到屏幕 // ''单引号后面是struct,代表二次编码,可以把生成的json的key从大写变成小写 Company string `json:"company"` Subjects []string `json:"subjects"` IsOk bool `json:"isok"` //IsOk bool `json:"string"`//转成字符串再输出编码 Price float64 `json:"price"` } func main() { // 1. 定义一个结构体变量,同时初始化 s := IT{"itcast", []string{"Go", "C++", "Python", "Test"}, true, 666.666} // 2. 编码,根据内容生成json文本 buf, err := json.MarshalIndent(s, "", " ") //格式化编码 if err != nil { fmt.Println("err = ", err) return } fmt.Println("buf = ", string(buf)) }
map 生成json
package main import ( "encoding/json" "fmt" ) func main() { // 1. 创建一个map,注意value是万能指针类型 m := make(map[string]interface{}, 4) m["company"] = "itcast" m["subjects"] = []string{"Go", "C++", "Python", "Test"} m["isok"] = true m["price"] = 666.666 // 2. 编码成json //result, err := json.Marshal(m) result, err := json.MarshalIndent(m, "", " ") if err != nil { fmt.Println("err = ", err) return } fmt.Println("result = ", string(result)) }
json解析到map
package main import ( "encoding/json" "fmt" ) func main() { jsonBuf := ` { "company": "itcast", "subjects": [ "Go", "C++", "Python", "Test" ], "isok": true, "price": 666.666 }` // 1. 创建一个map m := make(map[string]interface{}, 4) // 2. 第二个参数要地址传递 err := json.Unmarshal([]byte(jsonBuf), &m) if err != nil { fmt.Println("err = ", err) return } fmt.Printf("m = %+v ", m) //var str string //str = string(m["company"])// err,无法转换, //str = m["company"].(string)// ok.或者通过类型断言取map的内容。 //fmt.Printf("str = %s ", str) // 3. 类型断言, 值,它是value类型 var str string for key, value := range m { //fmt.Printf("%v ============> %v ", key, value) switch data := value.(type) { case string: str = data fmt.Printf("map[%s]的值类型为string, value = %s ", key, str) case bool: fmt.Printf("map[%s]的值类型为bool, value = %v ", key, data) case float64: fmt.Printf("map[%s]的值类型为float64, value = %f ", key, data) case []string: fmt.Printf("map[%s]的值类型为[]string, value = %v ", key, data) case []interface{}: fmt.Printf("map[%s]的值类型为[]interface, value = %v ", key, data) } } }
json解析到结构体
package main import ( "encoding/json" "fmt" ) type IT struct { Company string `json:"company"` Subjects []string `json:"subjects"` //二次编码 IsOk bool `json:"isok"` Price float64 `json:"price"` } func main() { jsonBuf := ` { "company": "itcast", "subjects": [ "Go", "C++", "Python", "Test" ], "isok": true, "price": 666.666 }` // 一 获取json全部的内容 // 1. 定义一个结构体变量 var tmp IT // 2. 第二个参数要地址传递,否则无法修改变量的值 err := json.Unmarshal([]byte(jsonBuf), &tmp) if err != nil { fmt.Println("err = ", err) return } //fmt.Println("tmp = ", tmp) fmt.Printf("tmp = %+v ", tmp) // 二 获取json指定的内容 type IT2 struct { Subjects []string `json:"subjects"` //二次编码 } var tmp2 IT2 err = json.Unmarshal([]byte(jsonBuf), &tmp2) //第二个参数要地址传递 if err != nil { fmt.Println("err = ", err) return } fmt.Printf("tmp2 = %+v ", tmp2) }
在Go语言中,[]byte(jsonBuf)这个表达式的作用是将一个名为jsonBuf的字节切片(byte slice)转换为[]byte类型。这里涉及到了Go语言中的类型转换概念。
在Go中,[]byte是一个切片(slice)类型,它底层的类型是byte,即uint8。这意味着[]byte可以包含任意数量的字节,每个字节都是uint8类型的值。当我们使用[]byte(jsonBuf)时,我们实际上是在告诉Go将jsonBuf这个变量的内容——假设它是一个字节切片——转换成一个新的[]byte切片。
这种转换通常用在以下几种场景:
类型匹配:有时候你需要确保一个变量是[]byte类型,以便能够使用特定的方法或函数对其进行操作。
接口要求:Go的某些接口要求传入的参数是[]byte类型,例如,当你需要向一个函数传递一个可以被解码为JSON的对象时。
性能考虑:在某些性能敏感的场合,直接操作[]byte可能会比操作字符串(string)更高效,因为字符串在Go中是不可变的,而字节切片是可变的。
API规范:某些外部API或库可能期望接收[]byte类型的数据,这时你需要将其他类型的数据转换为[]byte。
简而言之,[]byte(jsonBuf)的作用是将jsonBuf这个字节切片转换为[]byte类型,以便在Go程序中进行进一步的字节操作。