github.com/ice-blockchain/go/src@v0.0.0-20240403114104-1564d284e521/reflect/example_test.go (about) 1 // Copyright 2012 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 package reflect_test 6 7 import ( 8 "bytes" 9 "encoding/json" 10 "fmt" 11 "io" 12 "os" 13 "reflect" 14 ) 15 16 func ExampleKind() { 17 for _, v := range []any{"hi", 42, func() {}} { 18 switch v := reflect.ValueOf(v); v.Kind() { 19 case reflect.String: 20 fmt.Println(v.String()) 21 case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: 22 fmt.Println(v.Int()) 23 default: 24 fmt.Printf("unhandled kind %s", v.Kind()) 25 } 26 } 27 28 // Output: 29 // hi 30 // 42 31 // unhandled kind func 32 } 33 34 func ExampleMakeFunc() { 35 // swap is the implementation passed to MakeFunc. 36 // It must work in terms of reflect.Values so that it is possible 37 // to write code without knowing beforehand what the types 38 // will be. 39 swap := func(in []reflect.Value) []reflect.Value { 40 return []reflect.Value{in[1], in[0]} 41 } 42 43 // makeSwap expects fptr to be a pointer to a nil function. 44 // It sets that pointer to a new function created with MakeFunc. 45 // When the function is invoked, reflect turns the arguments 46 // into Values, calls swap, and then turns swap's result slice 47 // into the values returned by the new function. 48 makeSwap := func(fptr any) { 49 // fptr is a pointer to a function. 50 // Obtain the function value itself (likely nil) as a reflect.Value 51 // so that we can query its type and then set the value. 52 fn := reflect.ValueOf(fptr).Elem() 53 54 // Make a function of the right type. 55 v := reflect.MakeFunc(fn.Type(), swap) 56 57 // Assign it to the value fn represents. 58 fn.Set(v) 59 } 60 61 // Make and call a swap function for ints. 62 var intSwap func(int, int) (int, int) 63 makeSwap(&intSwap) 64 fmt.Println(intSwap(0, 1)) 65 66 // Make and call a swap function for float64s. 67 var floatSwap func(float64, float64) (float64, float64) 68 makeSwap(&floatSwap) 69 fmt.Println(floatSwap(2.72, 3.14)) 70 71 // Output: 72 // 1 0 73 // 3.14 2.72 74 } 75 76 func ExampleStructTag() { 77 type S struct { 78 F string `species:"gopher" color:"blue"` 79 } 80 81 s := S{} 82 st := reflect.TypeOf(s) 83 field := st.Field(0) 84 fmt.Println(field.Tag.Get("color"), field.Tag.Get("species")) 85 86 // Output: 87 // blue gopher 88 } 89 90 func ExampleStructTag_Lookup() { 91 type S struct { 92 F0 string `alias:"field_0"` 93 F1 string `alias:""` 94 F2 string 95 } 96 97 s := S{} 98 st := reflect.TypeOf(s) 99 for i := 0; i < st.NumField(); i++ { 100 field := st.Field(i) 101 if alias, ok := field.Tag.Lookup("alias"); ok { 102 if alias == "" { 103 fmt.Println("(blank)") 104 } else { 105 fmt.Println(alias) 106 } 107 } else { 108 fmt.Println("(not specified)") 109 } 110 } 111 112 // Output: 113 // field_0 114 // (blank) 115 // (not specified) 116 } 117 118 func ExampleTypeOf() { 119 // As interface types are only used for static typing, a 120 // common idiom to find the reflection Type for an interface 121 // type Foo is to use a *Foo value. 122 writerType := reflect.TypeOf((*io.Writer)(nil)).Elem() 123 124 fileType := reflect.TypeOf((*os.File)(nil)) 125 fmt.Println(fileType.Implements(writerType)) 126 127 // Output: 128 // true 129 } 130 131 func ExampleStructOf() { 132 typ := reflect.StructOf([]reflect.StructField{ 133 { 134 Name: "Height", 135 Type: reflect.TypeOf(float64(0)), 136 Tag: `json:"height"`, 137 }, 138 { 139 Name: "Age", 140 Type: reflect.TypeOf(int(0)), 141 Tag: `json:"age"`, 142 }, 143 }) 144 145 v := reflect.New(typ).Elem() 146 v.Field(0).SetFloat(0.4) 147 v.Field(1).SetInt(2) 148 s := v.Addr().Interface() 149 150 w := new(bytes.Buffer) 151 if err := json.NewEncoder(w).Encode(s); err != nil { 152 panic(err) 153 } 154 155 fmt.Printf("value: %+v\n", s) 156 fmt.Printf("json: %s", w.Bytes()) 157 158 r := bytes.NewReader([]byte(`{"height":1.5,"age":10}`)) 159 if err := json.NewDecoder(r).Decode(s); err != nil { 160 panic(err) 161 } 162 fmt.Printf("value: %+v\n", s) 163 164 // Output: 165 // value: &{Height:0.4 Age:2} 166 // json: {"height":0.4,"age":2} 167 // value: &{Height:1.5 Age:10} 168 } 169 170 func ExampleValue_FieldByIndex() { 171 // This example shows a case in which the name of a promoted field 172 // is hidden by another field: FieldByName will not work, so 173 // FieldByIndex must be used instead. 174 type user struct { 175 firstName string 176 lastName string 177 } 178 179 type data struct { 180 user 181 firstName string 182 lastName string 183 } 184 185 u := data{ 186 user: user{"Embedded John", "Embedded Doe"}, 187 firstName: "John", 188 lastName: "Doe", 189 } 190 191 s := reflect.ValueOf(u).FieldByIndex([]int{0, 1}) 192 fmt.Println("embedded last name:", s) 193 194 // Output: 195 // embedded last name: Embedded Doe 196 } 197 198 func ExampleValue_FieldByName() { 199 type user struct { 200 firstName string 201 lastName string 202 } 203 u := user{firstName: "John", lastName: "Doe"} 204 s := reflect.ValueOf(u) 205 206 fmt.Println("Name:", s.FieldByName("firstName")) 207 // Output: 208 // Name: John 209 }