Ian Lance Taylor | b156d71 | 2016-07-22 07:41:34 -0700 | [diff] [blame] | 1 | // Copyright 2012 The Go Authors. All rights reserved. |
Ian Lance Taylor | d7936ea | 2012-10-22 17:50:02 -0700 | [diff] [blame] | 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 ( |
Ian Lance Taylor | 0ba4563 | 2017-01-13 11:17:23 -0800 | [diff] [blame] | 8 | "bytes" |
| 9 | "encoding/json" |
Ian Lance Taylor | d7936ea | 2012-10-22 17:50:02 -0700 | [diff] [blame] | 10 | "fmt" |
Ian Lance Taylor | 5e7ded0 | 2015-10-30 16:02:38 -0700 | [diff] [blame] | 11 | "io" |
| 12 | "os" |
Ian Lance Taylor | d7936ea | 2012-10-22 17:50:02 -0700 | [diff] [blame] | 13 | "reflect" |
| 14 | ) |
| 15 | |
Ian Lance Taylor | c76ba30 | 2019-01-09 06:57:38 -0800 | [diff] [blame] | 16 | func ExampleKind() { |
| 17 | for _, v := range []interface{}{"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 | |
Ian Lance Taylor | d7936ea | 2012-10-22 17:50:02 -0700 | [diff] [blame] | 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 interface{}) { |
| 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 | } |
Ian Lance Taylor | f8f0cb4 | 2013-11-06 11:23:33 -0800 | [diff] [blame] | 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 | } |
Ian Lance Taylor | 5e7ded0 | 2015-10-30 16:02:38 -0700 | [diff] [blame] | 89 | |
Ian Lance Taylor | b156d71 | 2016-07-22 07:41:34 -0700 | [diff] [blame] | 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 | |
Ian Lance Taylor | 5e7ded0 | 2015-10-30 16:02:38 -0700 | [diff] [blame] | 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 | } |
Ian Lance Taylor | 0ba4563 | 2017-01-13 11:17:23 -0800 | [diff] [blame] | 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 | } |