summaryrefslogtreecommitdiffstats
path: root/src/reflect/example_test.go
diff options
context:
space:
mode:
Diffstat (limited to 'src/reflect/example_test.go')
-rw-r--r--src/reflect/example_test.go209
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
+}