...

Source file src/reflect/example_test.go

Documentation: reflect

     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  }
   210  

View as plain text