一、反射介绍
* 在Go语言标准库中reflect包提供了运行时反射,程序运行过程中动态操作结构体
* 当变量存储结构体属性名称,想要对结构体这个属性赋值或查看时,就可以使用反射.
* 反射还可以用作判断变量类型
* 整个reflect包中最重要的两个类型
* reflect.Type 类型
* reflect.Value 值
* 获取到Type和Value的函数
* reflect.TypeOf(interface{}) 返回Type
* reflect.ValueOf(interface{}) 返回值Value
* 判断变量类型
a:=1.5
fmt.Println(reflect.TypeOf(a))
* 获取结构体属性的值
ype People struct {
Id int
Name string
}
func main() {
peo := People{1, "张三"}
//获取peo的值
v := reflect.ValueOf(peo)
//获取属性个数,如果v不是结构体类型panic
fmt.Println(v.NumField())
//获取第0个属性,id,并转换为int64类型
fmt.Println(v.Field(0).Int())
//获取第1个属性,转换换为string类型
fmt.Println(v.Field(1).String())
//根据名字获取类型,并把类型名称转换为string类型
idValue := v.FieldByName("Id")
fmt.Println(idValue.Kind().String())
}
* 设置结构体属性的值时要传递结构体指针,否者无法获取设置的结构体对象
* 反射直射结构体属性时,要求属性名首字母必须大写,否则无法设置
package main
import (
"fmt"
"reflect"
)
type People struct {
Id int
Name string
}
func main() {
peo := People{1, "张三"}
/*
反射时获取peo的地址.
Elem()获取指针指向地址的封装.
地址的值必须调用Elem()才可以继续操作
*/
v := reflect.ValueOf(&peo).Elem()
fmt.Println(v.FieldByName("Id").CanSet())
v.FieldByName("Id").SetInt(123)
v.FieldByName("Name").SetString("李四")
fmt.Println(peo)
}
二、XML文件简介
* 英文全称:Extensible Markup Language
* 中文全称:可扩展标记语言
* 用途:
* 数据存储
* 数据交互
* 配置文件
* 优点:
* 跨平台性
* 数据工整,易读
* XML文档结构
* 第一行:XML头,版本和编码
* 第二行:DTD可选,能够检查XML内容是否满足要求
* 最外层标签
*
* id=”1” 属性节点
* 标签中文字:文本节点
* 语法要求
* 严格区分大小写
* 标签必须正确嵌套,必须正确关闭
* 必须有根节点
* 属性值必须有双引号
* 注释:
* 文本节点出现特殊字符,需要使用实体引用替换
三、XML文件内容读取
* Go语言标准库提供的API
* 在encoding/xml包下提供了对XML序列化和反序列化的API
* 使用Unmarshal可以直接把XML字节切片数据转换为结构体
* 转换时按照特定的转换规则进行转换,且数据类型可以自动转换
* 代码示例
* 给定XML文件内容如下
北京海淀
* 新建结构体,装载XML数据
* 结构体中属性首字母必须大写,否则无法装配
type People struct {
XMLName xml.Name `xml:"people"`
Id int `xml:"id,attr"`
Name string `xml:"name"`
Address string `xml:"address"`
}
func main() {
peo := new(People)
b, err := ioutil.ReadFile("demo.xml")
fmt.Println(string(b))
fmt.Println("111:", err)
err = xml.Unmarshal(b, peo)
fmt.Println("2222", err)
fmt.Println(peo)
}
四、XML文件生成
* 生成XML需要encoding/xml包下的Marshal()函数,结合输入流就可以完成xml文件生成
* 在encoding/xml中有常量,常量中是xml文档头
* 使用Marshal()函数生成的[]byte没有格式化
* 使用MarshalIndent()可以对内容进行格式化
* 第一个参数:结构体对象
* 第二个参数:每行的前缀
* 第三个参数:层级缩进内容
type People struct {
XMLName xml.Name `xml:"people"`
Id int `xml:"id,attr"`
Name string `xml:"name"`
Address string `xml:"address"`
}
func main() {
peo := People{Id: 123, Name: "smallming", Address: "北京海淀"}
b, _ := xml.MarshalIndent(peo, "", " ")
b = append([]byte(xml.Header), b...)
ioutil.WriteFile("D:/peo.xml", b, 0666)
fmt.Println("程序结束")
}
五、日志简介
* 使用开发工具时,控制台打印的信息就是日志信息
* 项目最终发布后是没有开发工具的。如果需要记录日志就要把信息输出到文件中,这个功能也是日志的功能
* 在Go语言标准的log包中提供了对日志的支持
* 有三种级别日志输出
* Print() 输出日志信息
* Panic() 打印日志信息,并触发panic,日志信息为Panic信息
* Fatal() 打印日志信息后调用os.Exit(1)
* 所有日志信息打印时都带有时间,且颜色为红色
* 每种级别日志打印都提供了三个函数
* Println()
* Print()
* Printf()
* 日志文件扩展名为log
六、普通日志信息打印
* 直接使用log包调用Println()即可
log.Println("打印日志信息")
七、Panic日志信息打印
* 执行后输出日志信息,同时也会触发panic
log.Panicln("打印日志信息")
八、致命日志信息
* 执行日志打印后,程序被终止
log.Fatal("打印日志信息")
九、打印日志信息到文件中
* Go语言标准库支持输出日志信息到文件中.
f, _ := os.OpenFile("D:/golog.log", os.O_APPEND|os.O_CREATE, 07777)
defer f.Close()
logger := log.New(f, "[info]\t", log.Ltime)
logger.Println("输出日志信息")