golang ?-?@amazeUI ?-?2017-11-02 11:18:07
type User struct {
????Name string
????Age ?int
????Id ? int
}
func (u User) GetName(name string) { //將匿名方法綁定到結(jié)構(gòu)體中
????fmt.Println("我的名字叫", u.Name, "傳進(jìn)來(lái)的是", name)
}
func main() {
????a := User{"xiaoming", 5, 6}
????a.GetName("測(cè)試1")
????Setname(&a)
????a.GetName("測(cè)試2")
????fmt.Println(a.Name)
????info(a)
????ra := reflect.ValueOf(a)
????rm := ra.MethodByName("GetName")
????args := []reflect.Value{reflect.ValueOf("測(cè)試三")} //通過(guò)反射調(diào)用該對(duì)象方法
????//這里再次回到切片與數(shù)組丧叽。到底什么是切片绞蹦,什么是數(shù)組
????//再次總結(jié)一下飞傀,剛看了點(diǎn)資料,以下是鏈接
????//https://www.zhihu.com/question/66673454
????//以下是總結(jié)
????//1.數(shù)組要指明長(zhǎng)度Array := [ArrayLength] ElementType,arr :=[4]int,數(shù)組拷貝為值拷貝
????//2.切片不需要指明長(zhǎng)度SliceT := []ElementType,但是他有容量機(jī)制,拷貝為指針拷貝
????arr := [4]int{0, 1, 3, 4}
????arrs := arr[1:2]
????ccc := reflect.TypeOf(arrs).Kind() //通過(guò)反射判斷是一個(gè)數(shù)組還是切片
????fmt.Println(ccc)
????rm.Call(args)
}
func info(o interface{}) { //獲取這個(gè)實(shí)例化了的結(jié)構(gòu)體的所有信息
????ot := reflect.TypeOf(o) ?//通過(guò)反射獲取類型
????ov := reflect.ValueOf(o) //獲取值
????fmt.Println(ot, "\n")
????fmt.Println(ov, "\n")
????fmt.Println(ot.Name(), "\n") ? ? ? ? ? ?//打印這個(gè)實(shí)現(xiàn)了空接口的結(jié)構(gòu)名稱
????for i := 0; i < ot.NumField(); i += 1 { //獲取這個(gè)結(jié)構(gòu)體內(nèi)的值
????????n := ot.Field(i)
????????val := ov.Field(i)
????????fmt.Println(n.Type, ":", n.Name, ",", val)
????}
????for i := 0; i < ot.NumMethod(); i += 1 { //打印這個(gè)結(jié)構(gòu)體的每個(gè)方法
????????f := ot.Method(i)
????????fmt.Printf("%s:%v,%v\n", f.Name, f.Type, f.Index)
????}
}
func Setname(o interface{}) { //通過(guò)反射設(shè)置值
????v := reflect.ValueOf(o)
????fmt.Println(v.Elem()) ? ? ? ? ?//這里打印出來(lái)是這個(gè)結(jié)構(gòu)體
????fmt.Println(v.Elem().CanSet()) //這里返回的是個(gè)布爾
????fmt.Println(v.Kind()) ? ? ? ? ?//這里打印出來(lái)的就是ptr
????fmt.Println(reflect.Ptr) ? ? ? //也是ptr,引出個(gè)問(wèn)題,為什么不用字符串"ptr"?以后再找答案,指針
????fmt.Println(v)
????//Elem返回v持有的接口保管的值的Value封裝,
????//或者v持有的指針指向的值的Value封裝菩佑。如果v的Kind不是Interface或Ptr會(huì)panic;如果v持有的值為nil凝化,會(huì)返回Value零值稍坯。
????//Kind返回v持有的值的分類,如果v是Value零值搓劫,返回值為Invalid
????if v.Kind() == reflect.Ptr && !v.Elem().CanSet() { //如果是指針且不能被修改
????????fmt.Println("xxx") //這個(gè)判斷有問(wèn)題,如果不是指針也會(huì)走else,或者可以修改但不是指針也會(huì)走else
????????return
????} else {
????????v = v.Elem()
????}
????n := v.FieldByName("Name")
????if n.IsValid() && n.Kind() == reflect.String { //如果取到了值并且類型是字符串則修改
????????fmt.Println(n, "\n", n.Kind())
????????n.SetString("lele") //修改名字//通過(guò)反射對(duì)值進(jìn)行修改劣光,肯定可以修改拉,傳進(jìn)來(lái)的是指針
????}
}
下面是執(zhí)行結(jié)果
我的名字叫 xiaoming 傳進(jìn)來(lái)的是 測(cè)試1
{xiaoming 5 6}
true
ptr
ptr
&{xiaoming 5 6}
xiaoming
string
我的名字叫 lele 傳進(jìn)來(lái)的是 測(cè)試2
lele
main.User
{lele 5 6}
User
string : Name , lele
int : Age , 5
int : Id , 6
GetName:func(main.User, string),0
slice
我的名字叫 lele 傳進(jìn)來(lái)的是 測(cè)試三
成功: 進(jìn)程退出代碼 0.