今天出了點意外,不一定有時間趕完昨天WebSocket的東西,所以先把之前研究到一半的文章先丟出來,萬分抱歉
反射Reflection是一種為了能在「執行期間」獲取對象方法或屬性的一種能力。雖然反射較為吃效能,但可以幫助抽象及簡化程式碼,提高開發效率。
直接使用一次看看吧,反射相關功能都定義在reflect package
import "reflect"
使用TypeOf()可以獲取一個實體的型別,在取得TypeOf之後可以進行一系列的操作,官方的Type內有完整的程式碼可以看。
func main() {
    var a int
    var b string
    var m (map[string]string)
    typeOf_A := reflect.TypeOf(a)
    typeOf_B := reflect.TypeOf(b)
    typeOf_M := reflect.TypeOf(m)
    fmt.Println("typeff_A:", typeOf_A)
    fmt.Println("typeOf_B:", typeOf_B)
    fmt.Println("typeOf_M:", typeOf_M)
}
output:
typeff_A: int
typeOf_B: string
typeOf_M: map[string]string
Name可以獲得自訂型別的名稱,Kind可以獲得該類別的名稱,以map與自訂型別Student試一次
func main() {
    type Student struct {
    	Name   string
    	Height float64
    }
    ming := Student{"Ming", 172.0} 
    
    m := map[string]int{
    	"ming":   172,
    	"BenLee": 169,
    }
    
    typeOfMing := reflect.TypeOf(ming)
    typeOfM := reflect.TypeOf(m)
    fmt.Println("typeOfMing Name:", typeOfMing.Name(), "Kind:", typeOfMing.Kind())
	fmt.Println("typeOfM Name:", typeOfM.Name(), "Kind:", typeOfM.Kind())
}
output:
typeOfMing Name: Student Kind: struct
typeOfM Name: Kind: map
透過NumField獲取結構內的資料
func main() {
    type Student struct {
    	Name   string
    	Height float64
    	Weight int
    }
    ming := Student{"Ming", 170.0, 75}    
    
    typeOfMing := reflect.TypeOf(ming)
    for i := 0; i < typeOfMing.NumField(); i++ {
    	file := typeOfMing.Field(i)
    	fmt.Println(file.Name, file.Type)
    }
}
output:
Name string
Height float64
Weight int
Type()的部分先到這邊,還有很多功能我也沒什麼頭緒,之後如果用到再回來補充QQ
若是想取得資料的值,則需要使用reflect.ValueOf()獲取Value物件後進行操作。Value的官方內容。
func main() {
    type Student struct {
    	Name   string
    	Height float64
    	Weight int
    }
    ming := Student{"Ming", 170.0, 75}
    valueOfMing := reflect.ValueOf(ming)
    fmt.Println("print all:",valueOfMing)
    fmt.Println("name:", valueOfMing.FieldByName("Name"))
    fmt.Println("height:", valueOfMing.FieldByName("Height"))
    fmt.Println("weight:", valueOfMing.FieldByName("Weight"))
}
output:
print all: {Ming 170 75}
print name: Ming
print height: 170
print weight: 75
若傳入的是指標類型,則必須使用Elem()來取得資料,繼續原本的例子
func main() {
    type Student struct {
    	Name   string
    	Height float64
    	Weight int
    }
    ming := &Student{"Ming", 170.0, 75}
    valueOfMing := reflect.ValueOf(ming).Elem()
    fmt.Println("print all:", valueOfMing)
    fmt.Println("name:", valueOfMing.FieldByName("Name"))
}
可以交叉比對一下沒使用Elem(),以及傳入指標的差距。
介紹的這麼沒底過,看好久還是看不出reflect可以用在什麼地方,一直不斷地介紹用法而已,明天會繼續回歸WebSocket的應用