Go语言学习教程(十四)

一、反射介绍

* 在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文件内容如下

       

       

            smallming

           

北京海淀

       



        * 新建结构体,装载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("输出日志信息")

你可能感兴趣的:(Go语言学习教程(十四))