<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ??碼云GVP開源項目 12k star Uniapp+ElementUI 功能強大 支持多語言、二開方便! 廣告
                [TOC] # 變量的內在機制 1. 類型信息,這部分是元信息,是預先定義好的 2. 值類型,這部分是程序運行過程中,動態改變的 反射機制就是在運行時動態的調用對象的方法和屬性,官方自帶的reflect包就是反射相關的,只要包含這個包就可以使用。 多插一句,Golang的gRPC也是通過反射實現的。 # 反射與空接口 空接口可以存儲任何類型的變量 那么給你一個空接口,怎么判斷里面存儲的是什么東西? 在運行時動態的獲取一個變量的類型和值信息就叫反射 內置包: reflect 獲取類型信息: reflect.TypeOf 獲取值信息: reflect.ValueOf # 反射種類(kind)定義 Go程序中的類型(Type)指的是系統原生數據類型,如int、string、bool、float32等類型,以及使用type關鍵字定義的類型,這些類型的名稱就是其類型本身的名稱。例如使用typeAstruct{}定義結構體時,A就是struct{}的類型。種類(Kind)指的是對象歸屬的品種,在reflect包中有如下定義 ~~~ type Kind uint const ( Invalid Kind = iota // 非法類型 Bool // 布爾型 Int // 有符號整型 Int8 // 有符號8位整型 Int16 // 有符號16位整型 Int32 // 有符號32位整型 Int64 // 有符號64位整型 Uint // 無符號整型 Uint8 // 無符號8位整型 Uint16 // 無符號16位整型 Uint32 // 無符號32位整型 Uint64 // 無符號64位整型 Uintptr // 指針 Float32 // 單精度浮點數 Float64 // 雙精度浮點數 Complex64 // 64位復數類型 Complex128 // 128位復數類型 Array // 數組 Chan // 通道 Func // 函數 Interface // 接口 Map // 映射 Ptr // 指針 Slice // 切片 String // 字符串 Struct // 結構體 UnsafePointer // 底層指針 ) ~~~ Map、Slice、Chan屬于引用類型,使用起來類似于指針,但是在種類常量定義中仍然屬于獨立的種類,不屬于Ptr。type A struct{}定義的結構體屬于Struct種類,\*A屬于Ptr # TypeOf和ValueOf ~~~ func reflect_example(a interface{}) { t := reflect.TypeOf(a) fmt.Printf("type of a is %v\n", t) v := reflect.ValueOf(a) fmt.Printf("value of a is %v\n", v) k := t.Kind() fmt.Println(k) } func main() { var x int64 = 3 reflect_example(x) } ~~~ # 運行時修改值 ~~~ func reflect_example(a interface{}) { v := reflect.ValueOf(a) k := v.Kind() switch k { case reflect.Int64: fmt.Printf("a is int64, store value is: %d\n", v.Int()) case reflect.Float64: fmt.Printf("a is Float64, store value is: %f\n", v.Float()) case reflect.Ptr: //指針類型 .Elem()相當于 指針取值 v.Elem().SetFloat(22.5) fmt.Println("指針") default: fmt.Println("default") } } func main() { var x float64 = 3.4 reflect_example(&x) fmt.Println(x) } ~~~ ~~~ var x float64 = 3.4 //這邊要傳地址,不然反射的是副本,下面修改副本的值會報錯 v1 := reflect.ValueOf(&x) //這邊已經是指針,要用Elem,通過Elem()獲取指針指向的變量,從而完成賦值操作 v1.Elem().SetFloat(4.3) fmt.Println(v1.Elem().Float()) ~~~ # 結構體屬性 ~~~ type Student struct { Name string Sex int Age int //abc string } func main() { var s Student v := reflect.ValueOf(s) t := v.Type() kind := t.Kind() fmt.Println(kind) //struct //查看字段數量,包含私有字段 fmt.Println(v.NumField()) //注意,私有獲取不到,會報錯的 for i := 0; i < v.NumField(); i++ { field := v.Field(i) fmt.Printf("名字: %s 類型: %v 值: %v\n", t.Field(i).Name, field.Type(), field.Interface()) } //修改結構體內部的值 v1 := reflect.ValueOf(&s) //用索引方式 v1.Elem().Field(0).SetString("abc") //指定名稱方式 v1.Elem().FieldByName("Sex").SetInt(2) v1.Elem().FieldByName("Age").SetInt(12) fmt.Println(s) } ~~~ 輸出 ~~~ struct 3 名字: Name 類型: string 值: 名字: Sex 類型: int 值: 0 名字: Age 類型: int 值: 0 {abc 2 12} ~~~ # 結構體方法 ~~~ func (s *Student) Test() { fmt.Println("this is test") } func main() { s := Student{23, "skidoo"} v := reflect.ValueOf(&s) t := v.Type() v.Elem().Field(0).SetInt(100) fmt.Println("method num: ", v.NumMethod()) for i := 0; i < v.NumMethod(); i++ { f := t.Method(i) fmt.Printf("%d method, name: %v, type: %v\n", i, f.Name, f.Type) } } ~~~ 輸出 ~~~ method num: 1 0 method, name: Test, type: func(*main.Student) ~~~ # 調用結構體方法 ~~~ type Student struct { A int B string } func (s *Student) Test() { fmt.Println("this is test") } func (s *Student) SetA (a int) { s.A = a } func main() { s := Student{23, "skidoo"} //要引用傳遞,不然修改的是副本會報錯 v := reflect.ValueOf(&s) m := v.MethodByName("Test") var args1 []reflect.Value m.Call(args1) setA := v.MethodByName("SetA") var args2 []reflect.Value //參數 args2 = append(args2, reflect.ValueOf(100)) setA.Call(args2) fmt.Printf("s: %#v\n", s) } ~~~ 輸出 ~~~ this is test s: main.Student{A:100, B:"skidoo"} ~~~ # 獲取結構體中的tag信息 ~~~ type Student struct { F string `species:"gopher" color:"blue" json:"f"` } func main() { s := Student{} //要引用傳遞,不然修改的是副本會報錯 v := reflect.TypeOf(s) field := v.Field(0) fmt.Println(field.Tag.Get("color"), field.Tag.Get("species"), field.Tag.Get("json")) ~~~ 輸出 ~~~ blue gopher f ~~~
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看