9.1反射 在Go語言標準庫中reflect包提供了運行時反射,程式運行過程中動態操作結構體 當變數存儲結構體屬性名稱,想要對結構體這個屬性賦值或查看時,就可以使用反射 反射還可以用作判斷變數類型 整個reflect包中最重要的兩個類型 reflect.Type類型 reflect.Value值 獲 ...
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("程式結束") }