• 9.Go-反射、日志和线程休眠


    9.1反射

    在Go语言标准库中reflect包提供了运行时反射,程序运行过程中动态操作结构体

    当变量存储结构体属性名称,想要对结构体这个属性赋值或查看时,就可以使用反射

    反射还可以用作判断变量类型

    整个reflect包中最重要的两个类型

    • reflect.Type类型
    • reflect.Value值

    获取到Type和Value的函数

    • reflect.TypeOf(interface{})返回type
    • reflect.ValueOf(interface{})返回值Value

      (1)获取变量属性和值

    //Learn_Go/main.go
    package main
    
    import (
    	"fmt"
    	"reflect"
    )
    
    func main() {
    	a := 1.5
    	fmt.Println(reflect.TypeOf(a))       //float64
    	fmt.Println(reflect.ValueOf(a))      //1.5
    }
    

     (2)获取结构体属性的值

    //Learn_Go/main.go
    package main
    
    import (
    	"fmt"
    	"reflect"
    )
    
    type People struct {
    	name string
    	address string
    }
    func main() {
    	peo := People{"derek","guangdong"}
    	v := reflect.ValueOf(peo)
    	//有多少个字段
    	fmt.Println(v.NumField())                  //2
    	//根据索引获取字段值
    	fmt.Println(v.FieldByIndex([]int {0}))     //derek
    	
    	content := "address"
    	fmt.Println(v.FieldByName(content))       //guangdong
    }
    

     (3)设置结构体属性的值

    反射时获取peo的地址,Elem()获取指针指向地址的封装

    //Learn_Go/main.go
    package main
    
    import (
    	"fmt"
    	"reflect"
    )
    
    type People struct {
    	Name string
    	Address string
    }
    func main() {
    	content := "Name"
    	peo := new(People)
    	//Elem()获取指针对应元素的值
    	v := reflect.ValueOf(peo).Elem()
    	//CanSet():判断值有没有被设置,有设置:True,没有设置:false
    	fmt.Println(v.FieldByName(content).CanSet())
    
    	//需要修改属性的内容时,要求结构体中属性名首字母大写才可以设置
    	v.FieldByName(content).SetString("alice")
    	v.FieldByName("Address").SetString("beijing")
    	fmt.Println(peo)       //&{alice beijing}
    }
    

     (4)结构体支持标记(tag),标记通常都是通过反射技术获取到 

    //Learn_Go/main.go
    package main
    
    import (
    	"fmt"
    	"reflect"
    )
    
    type People struct {
    	Name string `xml:"name"`
    	Address string
    }
    func main() {
    	t := reflect.TypeOf(People{})
    	fmt.Println(t.FieldByName("Name"))      //{Name  string xml:"name" 0 [0] false} true
    	name,_ := t.FieldByName("Name")
    	fmt.Println(name.Tag)                  //xml:"name"
    	fmt.Println(name.Tag.Get("xml"))       //name
    }
    

    9.2.日志

    有三种级别日志输出

    • Print() 输出日志信息
    • Panic()打印日志信息,并处罚panic,日志信息为Panic信息
    • Fatal()打印日志信息后调用os.Exit(0)

    所有日志信息打印时都带有时间,且颜色为红色,输出日志信息到文件中

    //Learn_Go/main.go
    package main
    
    import (
    	"log"
    	"os"
    )
    
    func main() {
    	f,_ := os.OpenFile("D:/golog.log",os.O_APPEND|os.O_CREATE,0777)
    	logger := log.New(f,"[Info]",log.Ltime)         //"[Info]":prefix string
    	logger.Println("打印日志信息")                  //[Info]22:13:59 打印日志信息
    }
    

    9.3.线程休眠和延迟执行

    (1)线程休眠 

    Go语言中main()函数为主线程(协程),程序是从上向下执行的

    可以通过time包下的Sleep(n)让程序阻塞多少纳秒

    //Learn_Go/main.go
    package main
    
    import (
    	"fmt"
    	"time"
    )
    
    func main() {
    	fmt.Println("111")
    	time.Sleep(2e9)     //2e9 相当于2秒
    	fmt.Println("222")
    }
    

    (2)延迟执行

    延迟指定时间后执行一次,但是需要注意在触发时程序没有结束

    //Learn_Go/main.go
    package main
    
    import (
    	"fmt"
    	"time"
    )
    
    func main() {
    	fmt.Println("程序开始")
    	time.AfterFunc(3e9, func() {
    		fmt.Println("延迟执行")
    	})
    	time.Sleep(4e9)    //必须阻塞4s,要不主程序执行完直接退出,不会执行“延迟执行”的代码
    	fmt.Println("程序结束")
    }
    
  • 相关阅读:
    响应式注意要添加“视口”约束标记---viewport
    js检测浏览器屏幕宽度
    Fragment中退出报错异常
    ListView和Gridview与滚动冲突解决
    APK反编译
    走出来,就要扛住
    与设备无法进行调试怎么走
    OC基础-protocol
    OC基础-变量可见对与方法
    OC基础-面向对象编程简介
  • 原文地址:https://www.cnblogs.com/gaidy/p/11887146.html
Copyright © 2020-2023  润新知