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内容是否满足要求

    * 最外层标签<peoples> 称为元素节点,根节点

    * <people>...<people> 整个标签称为元素节点

    * id=”1” 属性节点

    * 标签中文字:文本节点



* 语法要求

    * 严格区分大小写

    * 标签必须正确嵌套,必须正确关闭

    * 必须有根节点

    * 属性值必须有双引号

    * 注释:<!-- -->

    * 文本节点出现特殊字符,需要使用实体引用替换



三、XML文件内容读取

    * Go语言标准库提供的API

        * 在encoding/xml包下提供了对XML序列化和反序列化的API

        * 使用Unmarshal可以直接把XML字节切片数据转换为结构体

        * 转换时按照特定的转换规则进行转换,且数据类型可以自动转换



    * 代码示例

        * 给定XML文件内容如下

        <?xml version="1.0" encoding="UTF-8" ?>

        <people id="888">

            <name>smallming</name>

            <address>北京海淀</address>

        </people>



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

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 一、结构体指针 * 由于结构体是值类型,在方法传递时希望传递结构体地址,可以使用时结构体指针完成 * 可以结合ne...
    小陈工阅读 174评论 0 1
  • 一、匿名函数 * 匿名函数就是没有名称的函数 * 正常函数可以通过名称多次调用,而匿名函数由于没有函数名,所以大部...
    小陈工阅读 567评论 0 2
  • 一、断言 * 只要实现了接口的全部方法就认为这个类型属于接口类型,如果编写一个接口,这个接口中没有任何方法,这时认...
    小陈工阅读 317评论 0 4
  • 一、goto * goto是Go语言中的一个关键字 * goto让编译器执行时跳转到特定位置 * Loop是标记名...
    小陈工阅读 459评论 0 1
  • 接上节,获得可变参数类型,可变参数为interface{}类型时,可以传入任何类型的值。 func printTy...
    搬砖人1314阅读 224评论 0 0