2.15 Go語言反射例項
阿新 • • 發佈:2019-01-04
需求摘要
- 所有的商品都有一些共性,例如都有品名、價格,個性則無千無萬;
- 自行封裝出三種商品(以模擬30萬種商品)
- 隨意給出一個商品的集合,將每件商品的所有屬性值輸出到《品名.txt》檔案中;
需求分析
該需求的難點在於,給過來的商品是什麼型別都有的,每種不同型別的商品具體有些什麼屬性值我們完全無法預知——所以我們可以通過反射來得到這些屬性的名值;
匯入必要的包
import (
"os"
"encoding/json"
"fmt"
"reflect"
)
胡亂地封裝出一些商品
type Computer struct { Name string Price float64 Cpu string Memory int Disk int } type TShirt struct { Name string Price float64 Color string Size int Sex bool } type Car struct { Name string Price float64 Cap int Power string }
建立商品集合
products := make([]interface{}, 0)
products = append(products, Computer{"未來人類",10000,"英特爾i7",16,1024})
products = append(products, TShirt{"爆款T恤",10000,"紅色",40,false})
products = append(products, Car{"蘭博比基尼",10000,5,"油電混合"})
獲得所有商品的名稱
這裡我們要反射獲得一個叫做Name的屬性
for _,p := range products{ //先拿到p的值(不在乎型別) pValue := reflect.ValueOf(p) //再通過p值,拿到p下面的名為Name的屬性值 nameValue := pValue.FieldByName("Name") //Name屬性的值,反射形式化為正射形式(interface{}型別) nameInterface := nameValue.Interface() //將空介面斷言為string name := nameInterface.(string) fmt.Println(name) WriteObj2File(p,"D:/BJBlockChain180x/demos/W2/day4/file/"+name+".txt") }
上述程式碼還可以簡寫為
for _,p := range products{
name := reflect.ValueOf(p).FieldByName("Name").Interface().(string)
fmt.Println(name)
WriteObj2File(p,"D:/BJBlockChain180x/demos/W2/day4/file/"+name+".txt")
}
輸出商品資訊到指定檔案
這裡我們通過反射獲得了任意物件的所有屬性名值
func WriteObj2File(obj interface{},filename string) error { //開啟檔案 file, err := os.OpenFile(filename, os.O_CREATE|os.O_WRONLY|os.O_TRUNC, 0666) if err != nil{ return err } defer file.Close() //獲得例項資訊 oType := reflect.TypeOf(obj) oValue := reflect.ValueOf(obj) //獲取obj的所有屬性名值 for i:=0;i<oType.NumField();i++{ //屬性名 fName := oType.Field(i).Name //獲得屬性值的字串形式 fValue := oValue.FieldByName(fName).Interface() fValueStr := fmt.Sprint(fValue) //寫入檔案 _, err = file.WriteString(fName + ":" + fValueStr + "\n") if err != nil{ return err } } return nil }
總結
使用常規“正射”對未知型別進行操作難於登天,有了反射,EASY JOB!