diff options
Diffstat (limited to 'src/reflect/example_test.go')
-rw-r--r-- | src/reflect/example_test.go | 209 |
1 files changed, 209 insertions, 0 deletions
diff --git a/src/reflect/example_test.go b/src/reflect/example_test.go new file mode 100644 index 0000000..b4f3b29 --- /dev/null +++ b/src/reflect/example_test.go @@ -0,0 +1,209 @@ +// Copyright 2012 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package reflect_test + +import ( + "bytes" + "encoding/json" + "fmt" + "io" + "os" + "reflect" +) + +func ExampleKind() { + for _, v := range []any{"hi", 42, func() {}} { + switch v := reflect.ValueOf(v); v.Kind() { + case reflect.String: + fmt.Println(v.String()) + case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: + fmt.Println(v.Int()) + default: + fmt.Printf("unhandled kind %s", v.Kind()) + } + } + + // Output: + // hi + // 42 + // unhandled kind func +} + +func ExampleMakeFunc() { + // swap is the implementation passed to MakeFunc. + // It must work in terms of reflect.Values so that it is possible + // to write code without knowing beforehand what the types + // will be. + swap := func(in []reflect.Value) []reflect.Value { + return []reflect.Value{in[1], in[0]} + } + + // makeSwap expects fptr to be a pointer to a nil function. + // It sets that pointer to a new function created with MakeFunc. + // When the function is invoked, reflect turns the arguments + // into Values, calls swap, and then turns swap's result slice + // into the values returned by the new function. + makeSwap := func(fptr any) { + // fptr is a pointer to a function. + // Obtain the function value itself (likely nil) as a reflect.Value + // so that we can query its type and then set the value. + fn := reflect.ValueOf(fptr).Elem() + + // Make a function of the right type. + v := reflect.MakeFunc(fn.Type(), swap) + + // Assign it to the value fn represents. + fn.Set(v) + } + + // Make and call a swap function for ints. + var intSwap func(int, int) (int, int) + makeSwap(&intSwap) + fmt.Println(intSwap(0, 1)) + + // Make and call a swap function for float64s. + var floatSwap func(float64, float64) (float64, float64) + makeSwap(&floatSwap) + fmt.Println(floatSwap(2.72, 3.14)) + + // Output: + // 1 0 + // 3.14 2.72 +} + +func ExampleStructTag() { + type S struct { + F string `species:"gopher" color:"blue"` + } + + s := S{} + st := reflect.TypeOf(s) + field := st.Field(0) + fmt.Println(field.Tag.Get("color"), field.Tag.Get("species")) + + // Output: + // blue gopher +} + +func ExampleStructTag_Lookup() { + type S struct { + F0 string `alias:"field_0"` + F1 string `alias:""` + F2 string + } + + s := S{} + st := reflect.TypeOf(s) + for i := 0; i < st.NumField(); i++ { + field := st.Field(i) + if alias, ok := field.Tag.Lookup("alias"); ok { + if alias == "" { + fmt.Println("(blank)") + } else { + fmt.Println(alias) + } + } else { + fmt.Println("(not specified)") + } + } + + // Output: + // field_0 + // (blank) + // (not specified) +} + +func ExampleTypeOf() { + // As interface types are only used for static typing, a + // common idiom to find the reflection Type for an interface + // type Foo is to use a *Foo value. + writerType := reflect.TypeOf((*io.Writer)(nil)).Elem() + + fileType := reflect.TypeOf((*os.File)(nil)) + fmt.Println(fileType.Implements(writerType)) + + // Output: + // true +} + +func ExampleStructOf() { + typ := reflect.StructOf([]reflect.StructField{ + { + Name: "Height", + Type: reflect.TypeOf(float64(0)), + Tag: `json:"height"`, + }, + { + Name: "Age", + Type: reflect.TypeOf(int(0)), + Tag: `json:"age"`, + }, + }) + + v := reflect.New(typ).Elem() + v.Field(0).SetFloat(0.4) + v.Field(1).SetInt(2) + s := v.Addr().Interface() + + w := new(bytes.Buffer) + if err := json.NewEncoder(w).Encode(s); err != nil { + panic(err) + } + + fmt.Printf("value: %+v\n", s) + fmt.Printf("json: %s", w.Bytes()) + + r := bytes.NewReader([]byte(`{"height":1.5,"age":10}`)) + if err := json.NewDecoder(r).Decode(s); err != nil { + panic(err) + } + fmt.Printf("value: %+v\n", s) + + // Output: + // value: &{Height:0.4 Age:2} + // json: {"height":0.4,"age":2} + // value: &{Height:1.5 Age:10} +} + +func ExampleValue_FieldByIndex() { + // This example shows a case in which the name of a promoted field + // is hidden by another field: FieldByName will not work, so + // FieldByIndex must be used instead. + type user struct { + firstName string + lastName string + } + + type data struct { + user + firstName string + lastName string + } + + u := data{ + user: user{"Embedded John", "Embedded Doe"}, + firstName: "John", + lastName: "Doe", + } + + s := reflect.ValueOf(u).FieldByIndex([]int{0, 1}) + fmt.Println("embedded last name:", s) + + // Output: + // embedded last name: Embedded Doe +} + +func ExampleValue_FieldByName() { + type user struct { + firstName string + lastName string + } + u := user{firstName: "John", lastName: "Doe"} + s := reflect.ValueOf(u) + + fmt.Println("Name:", s.FieldByName("firstName")) + // Output: + // Name: John +} |