反射
运行时反射
reflect包提供了运行时反射,程序在运行过程中动态操作结构体,当变量存储结构体属性名称,想要对结构体这个属性赋值或查看时,就可以使用反射。
反射还可以用做判断变量类型,整个reflect包中重要的2个类型:reflect.Type 类型和reflect.Value值,获取到Type和Value的函数,reflect.TypeOf(interface{}) 返回Type,reflect.ValueOf(interface{}) 返回值Value。
案例
package main
import (
"fmt"
"reflect"
)
func main() {
// 反射
a := 1.5
t := reflect.TypeOf(a)
v := reflect.ValueOf(a)
fmt.Println(t)
fmt.Println(v)
a2 := People51{"张三", 67}
t2 := reflect.TypeOf(a2)
v2 := reflect.ValueOf(a2)
fmt.Println(t2)
fmt.Println(v2)
// 字段个数
fmt.Println("字段个数:", t2.NumField())
fmt.Println("字段个数:", v2.NumField())
// 根据下标获取
fmt.Println("获取第0个属性名:", t2.Field(0).Name)
fmt.Println("获取第0个属性值:", v2.Field(0).String())
fmt.Println("获取第1个属性名:", t2.Field(1).Name)
fmt.Println("获取第1个属性值:", v2.Field(1).Int())
// 获取
demo51_1()
// 设置结构体属性的值是要传递结构体指针,否则无法获取设置的结构体对象
demo51_2()
}
func demo51_2() {
a4 := People51_2{"张三", 67}
v4 := reflect.ValueOf(&a4).Elem()
nameValue4 := v4.FieldByName("Name")
ageValue42 := v4.FieldByName("Age")
fmt.Println("能否访问:", nameValue4.CanSet())
nameValue4.SetString("李四")
ageValue42.SetInt(32)
fmt.Println(a4) // {李四 32}
}
func demo51_1() {
a3 := People51_2{"张三", 67}
t3 := reflect.TypeOf(a3)
v3 := reflect.ValueOf(a3)
// 根据名称获取
nameType3, ok3 := t3.FieldByName("Name")
nameValue3 := v3.FieldByName("Name")
fmt.Println("name字段:", nameType3, ok3)
fmt.Println("name标签:", nameType3.Tag)
fmt.Println("name标签:", nameType3.Tag.Get("name"))
fmt.Println("name类型:", nameValue3.Kind().String())
fmt.Println("name值:", nameValue3)
ageType32, ok32 := t3.FieldByName("Age")
ageValue32 := v3.FieldByName("Age")
fmt.Println("age字段:", ageType32, ok32)
fmt.Println("age类型:", ageValue32.Kind().String())
fmt.Println("age值:", ageValue32)
}
type People51_2 struct {
Name string `name:"json"`
Age int
}
type People51 struct {
name string
age int
}
日志
log包
Go语言准备的log提供了对日志的支持,控制台打印的信息就是日志信息。有三种级别的日志输出:Print() 输出日志信息,Panic() 打印日志信息,并触发panic,日志信息为Panic信息;Fatal() 打印日志信息并调用: os.Exit(0)。所有日志信息打印时都还有时间,且颜色为红色,每种级别日志打印都提供了三个函数:Println(),Print(),Printf()。
案例
package main
import (
"fmt"
"log"
"os"
)
func main() {
// 日志
log.Println("输出日志信息") // 2022/12/15 16:04:18 输出日志信息
// log.Panicln("输出panic日志信息")
// log.Fatalln("输出fatal日志信息")
// 打印到文件
f, _ := os.OpenFile("d://Temp/go.log", os.O_APPEND|os.O_CREATE, 0660)
defer f.Close()
logger := log.New(f, "[info] ", log.Ltime)
logger.Println("输出日志信息=>文件")
fmt.Println("main end")
}
xml读取与生成
XML
英文全称:Extendsible Markup Language,可扩展标记语言,encoding/xml报文提供了对XML序列化和反序列化的API,使用Unmarshal可以直接把XML字节切片数据转换为结果报文,转换时按照特定的规则进行转换,且数据类型可以自动转换。
案例
package main
import (
"encoding/xml"
"fmt"
"os"
)
func main() {
// xml读取
p1 := new(People50)
// 相对于项目的路径
s1 := "demo01.xml"
bytes1, _ := os.ReadFile(s1)
xml.Unmarshal(bytes1, p1)
fmt.Println(p1)
p2 := new(Peoples50)
s2 := "demo02.xml"
bytes2, _ := os.ReadFile(s2)
xml.Unmarshal(bytes2, p2)
fmt.Println(p2)
}
type Peoples50 struct {
XMLName xml.Name `xml:"peoples"`
Version string `xml:"version,attr"`
// 首字母大写
Peoples []People50 `xml:"people"`
}
type People50 struct {
XMLName xml.Name `xml:"people"`
Id int `xml:"id,attr"`
Name string `xml:"name"`
Address string `xml:"address"`
Age int `xml:"age"`
}
<?xml version="1.0" encoding="UTF-8" ?>
<people id="606">
<name>刘甲</name>
<address>北京</address>
<age>19</age>
</people>
<?xml version="1.0" encoding="UTF-8" ?>
<peoples version="2.0">
<people id="606">
<name>刘甲</name>
<address>北京</address>
<age>19</age>
</people>
<people id="706">
<name>安乙</name>
<address>太原</address>
<age>5</age>
</people>
</peoples>
案例2
package main
import (
"encoding/xml"
"os"
)
const (
Header = `<?xml version="1.0" encoding="UTF-8" ?>` + "\n"
)
func main() {
// xml生成
// xml/encoding下的Marshal函数
p1 := People49{Id: 1, Name: "刘甲", Address: "北京", Age: 19}
// 相对于项目的路径
// bytes1, _ := xml.Marshal(p1)
bytes1, _ := xml.MarshalIndent(p1, "", " ")
bytes1 = append([]byte(Header), bytes1...)
s1 := "d:/Temp/case49.xml"
os.WriteFile(s1, bytes1, 0660)
// 输出第2个
ps2 := Peoples49{Version: "3.0"}
p2 := People49{Id: 2, Name: "安乙", Address: "北京", Age: 5}
parr2 := []People49{p1, p2}
ps2.Peoples = parr2
bytes2, _ := xml.MarshalIndent(ps2, "", " ")
bytes2 = append([]byte(Header), bytes2...)
s2 := "d:/Temp/demo02.xml"
os.WriteFile(s2, bytes2, 0660)
}
type Peoples49 struct {
XMLName xml.Name `xml:"peoples"`
Version string `xml:"version,attr"`
// 首字母大写
Peoples []People49 `xml:"people"`
}
type People49 struct {
XMLName xml.Name `xml:"people"`
Id int `xml:"id,attr"`
Name string `xml:"name"`
Address string `xml:"address"`
Age int `xml:"age"`
}
JSON
案例
package main
import (
"encoding/json"
"fmt"
)
func main() {
// JSON
p1 := People29{1, "张三", "北京", 1.34}
b1, _ := json.Marshal(p1)
fmt.Println(string(b1))
// {"id":1,"name":"张三","Address":"北京"}
p2 := new(People29)
json.Unmarshal(b1, p2)
fmt.Println(p2)
//
s3 := `{"id":1,"name":"张三","Address":"北京"}`
b3 := []byte(s3)
p3 := new(People29)
json.Unmarshal(b3, p3)
fmt.Println(p3)
}
// 要求属性名大写
type People29 struct {
Id int `json:"id"`
Name string `json:"name,omitempty"` // 没有name属性值,将会被忽略
Address string `json:",omitempty"` // 名字和属性名相同
Weight float64 `json:"-"` // JSON忽略
}
本文暂时没有评论,来添加一个吧(●'◡'●)