今天出了點意外,不一定有時間趕完昨天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的應用