├── .github └── workflows │ └── go.yml ├── .gitignore ├── LICENSE ├── README.md ├── all_test.go ├── benchmark_marshaler_test.go ├── benchmark_test.go ├── bridge.go ├── example_test.go ├── export_test.go ├── go.mod ├── go.sum ├── init.go ├── reflect.go ├── reflect113.go ├── reflect_test.go ├── set_test.go ├── tostring_test.go ├── type.go └── value.go /.github/workflows/go.yml: -------------------------------------------------------------------------------- 1 | name: Go 2 | on: [push] 3 | jobs: 4 | build: 5 | name: Test 6 | strategy: 7 | matrix: 8 | os: [ubuntu-latest, windows-latest, macos-latest] 9 | go-version: 10 | - '1.14.x' 11 | - '1.15.x' 12 | - '1.16.x' 13 | runs-on: ${{ matrix.os }} 14 | steps: 15 | - name: Set up Go ${{ matrix.go-version }} 16 | uses: actions/setup-go@v1 17 | with: 18 | go-version: ${{ matrix.go-version }} 19 | id: go 20 | 21 | - name: Check out code into the Go module directory 22 | uses: actions/checkout@v2 23 | 24 | - name: Test 25 | run: go test -v -coverprofile="coverage.out" ./ 26 | 27 | - name: Upload coverage 28 | uses: codecov/codecov-action@v1 29 | with: 30 | file: ./coverage.out 31 | fail_ci_if_error: true 32 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Binaries for programs and plugins 2 | *.exe 3 | *.exe~ 4 | *.dll 5 | *.so 6 | *.dylib 7 | 8 | # Test binary, built with `go test -c` 9 | *.test 10 | 11 | # Output of the go coverage tool, specifically when used with LiteIDE 12 | *.out 13 | 14 | # Dependency directories (remove the comment below to include it) 15 | # vendor/ 16 | 17 | .idea/ -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020 Masaaki Goshima 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # go-reflect 2 | 3 | ![Go](https://github.com/goccy/go-reflect/workflows/Go/badge.svg) 4 | [![GoDoc](https://godoc.org/github.com/goccy/go-reflect?status.svg)](https://pkg.go.dev/github.com/goccy/go-reflect?tab=doc) 5 | [![codecov](https://codecov.io/gh/goccy/go-reflect/branch/master/graph/badge.svg)](https://codecov.io/gh/goccy/go-reflect) 6 | [![Go Report Card](https://goreportcard.com/badge/github.com/goccy/go-reflect)](https://goreportcard.com/report/github.com/goccy/go-reflect) 7 | 8 | Zero-allocation reflection library for Go 9 | 10 | # Features 11 | 12 | - 100% Compatibility APIs with `reflect` library 13 | - No allocation occurs when using the reflect.Type features 14 | - You can choose to escape ( `reflect.ValueOf` ) or noescape ( `reflect.ValueNoEscapeOf` ) when creating reflect.Value 15 | 16 | # Status 17 | 18 | All the tests in the reflect library have been passed 19 | except the tests that use some private functions. 20 | 21 | # Installation 22 | 23 | ```bash 24 | go get github.com/goccy/go-reflect 25 | ``` 26 | 27 | # How to use 28 | 29 | Replace import statement from `reflect` to `github.com/goccy/go-reflect` 30 | 31 | ```bash 32 | -import "reflect" 33 | +import "github.com/goccy/go-reflect" 34 | ``` 35 | 36 | # Benchmarks 37 | 38 | Source https://github.com/goccy/go-reflect/blob/master/benchmark_test.go 39 | 40 | ## Benchmark about reflect.Type 41 | 42 | ``` 43 | $ go test -bench TypeOf 44 | ``` 45 | 46 | ``` 47 | goos: darwin 48 | goarch: amd64 49 | pkg: github.com/goccy/go-reflect 50 | Benchmark_TypeOf_Reflect-12 100000000 13.8 ns/op 8 B/op 1 allocs/op 51 | Benchmark_TypeOf_GoReflect-12 2000000000 1.70 ns/op 0 B/op 0 allocs/op 52 | PASS 53 | ok github.com/goccy/go-reflect 5.369s 54 | ``` 55 | 56 | ## Benchmark about reflect.Value 57 | 58 | ``` 59 | $ go test -bench ValueOf 60 | ``` 61 | 62 | ``` 63 | goos: darwin 64 | goarch: amd64 65 | pkg: github.com/goccy/go-reflect 66 | Benchmark_ValueOf_Reflect-12 100000000 13.0 ns/op 8 B/op 1 allocs/op 67 | Benchmark_ValueOf_GoReflect-12 300000000 4.64 ns/op 0 B/op 0 allocs/op 68 | PASS 69 | ok github.com/goccy/go-reflect 3.578s 70 | ``` 71 | 72 | # Real World Example 73 | 74 | ## Implements Fast Marshaler 75 | 76 | I would like to introduce the technique I use for [github.com/goccy/go-json](https://github.com/goccy/go-json). 77 | Using this technique, allocation can be suppressed to once for any marshaler. 78 | 79 | Original Source is https://github.com/goccy/go-reflect/blob/master/benchmark_marshaler_test.go 80 | 81 | ```go 82 | package reflect_test 83 | 84 | import ( 85 | "errors" 86 | "strconv" 87 | "sync" 88 | "testing" 89 | "unsafe" 90 | 91 | "github.com/goccy/go-reflect" 92 | ) 93 | 94 | var ( 95 | typeToEncoderMap sync.Map 96 | bufpool = sync.Pool{ 97 | New: func() interface{} { 98 | return &buffer{ 99 | b: make([]byte, 0, 1024), 100 | } 101 | }, 102 | } 103 | ) 104 | 105 | type buffer struct { 106 | b []byte 107 | } 108 | 109 | type encoder func(*buffer, unsafe.Pointer) error 110 | 111 | func Marshal(v interface{}) ([]byte, error) { 112 | 113 | // Technique 1. 114 | // Get type information and pointer from interface{} value without allocation. 115 | typ, ptr := reflect.TypeAndPtrOf(v) 116 | typeID := reflect.TypeID(typ) 117 | 118 | // Technique 2. 119 | // Reuse the buffer once allocated using sync.Pool 120 | buf := bufpool.Get().(*buffer) 121 | buf.b = buf.b[:0] 122 | defer bufpool.Put(buf) 123 | 124 | // Technique 3. 125 | // builds a optimized path by typeID and caches it 126 | if enc, ok := typeToEncoderMap.Load(typeID); ok { 127 | if err := enc.(encoder)(buf, ptr); err != nil { 128 | return nil, err 129 | } 130 | 131 | // allocate a new buffer required length only 132 | b := make([]byte, len(buf.b)) 133 | copy(b, buf.b) 134 | return b, nil 135 | } 136 | 137 | // First time, 138 | // builds a optimized path by type and caches it with typeID. 139 | enc, err := compile(typ) 140 | if err != nil { 141 | return nil, err 142 | } 143 | typeToEncoderMap.Store(typeID, enc) 144 | if err := enc(buf, ptr); err != nil { 145 | return nil, err 146 | } 147 | 148 | // allocate a new buffer required length only 149 | b := make([]byte, len(buf.b)) 150 | copy(b, buf.b) 151 | return b, nil 152 | } 153 | 154 | func compile(typ reflect.Type) (encoder, error) { 155 | switch typ.Kind() { 156 | case reflect.Struct: 157 | return compileStruct(typ) 158 | case reflect.Int: 159 | return compileInt(typ) 160 | } 161 | return nil, errors.New("unsupported type") 162 | } 163 | 164 | func compileStruct(typ reflect.Type) (encoder, error) { 165 | 166 | encoders := []encoder{} 167 | 168 | for i := 0; i < typ.NumField(); i++ { 169 | field := typ.Field(i) 170 | enc, err := compile(field.Type) 171 | if err != nil { 172 | return nil, err 173 | } 174 | offset := field.Offset 175 | encoders = append(encoders, func(buf *buffer, p unsafe.Pointer) error { 176 | return enc(buf, unsafe.Pointer(uintptr(p)+offset)) 177 | }) 178 | } 179 | return func(buf *buffer, p unsafe.Pointer) error { 180 | buf.b = append(buf.b, '{') 181 | for _, enc := range encoders { 182 | if err := enc(buf, p); err != nil { 183 | return err 184 | } 185 | } 186 | buf.b = append(buf.b, '}') 187 | return nil 188 | }, nil 189 | } 190 | 191 | func compileInt(typ reflect.Type) (encoder, error) { 192 | return func(buf *buffer, p unsafe.Pointer) error { 193 | value := *(*int)(p) 194 | buf.b = strconv.AppendInt(buf.b, int64(value), 10) 195 | return nil 196 | }, nil 197 | } 198 | 199 | func Benchmark_Marshal(b *testing.B) { 200 | b.ReportAllocs() 201 | for n := 0; n < b.N; n++ { 202 | bytes, err := Marshal(struct{ I int }{10}) 203 | if err != nil { 204 | b.Fatal(err) 205 | } 206 | if string(bytes) != "{10}" { 207 | b.Fatal("unexpected error") 208 | } 209 | } 210 | } 211 | ``` 212 | 213 | The benchmark result is as follows. 214 | 215 | ```bash 216 | 217 | $ go test -bench Benchmark_Marshal 218 | goos: darwin 219 | goarch: amd64 220 | pkg: github.com/goccy/go-reflect 221 | Benchmark_Marshal-16 16586372 71.0 ns/op 4 B/op 1 allocs/op 222 | PASS 223 | ``` 224 | 225 | -------------------------------------------------------------------------------- /benchmark_marshaler_test.go: -------------------------------------------------------------------------------- 1 | package reflect_test 2 | 3 | import ( 4 | "errors" 5 | "strconv" 6 | "sync" 7 | "testing" 8 | "unsafe" 9 | 10 | "github.com/goccy/go-reflect" 11 | ) 12 | 13 | var ( 14 | typeToEncoderMap sync.Map 15 | bufpool = sync.Pool{ 16 | New: func() interface{} { 17 | return &buffer{ 18 | b: make([]byte, 0, 1024), 19 | } 20 | }, 21 | } 22 | ) 23 | 24 | type buffer struct { 25 | b []byte 26 | } 27 | 28 | type encoder func(*buffer, unsafe.Pointer) error 29 | 30 | func Marshal(v interface{}) ([]byte, error) { 31 | 32 | // Technique 1. 33 | // Get type information and pointer from interface{} value without allocation. 34 | typ, ptr := reflect.TypeAndPtrOf(v) 35 | typeID := reflect.TypeID(v) 36 | 37 | // Technique 2. 38 | // Reuse the buffer once allocated using sync.Pool 39 | buf := bufpool.Get().(*buffer) 40 | buf.b = buf.b[:0] 41 | defer bufpool.Put(buf) 42 | 43 | // Technique 3. 44 | // builds a optimized path by typeID and caches it 45 | if enc, ok := typeToEncoderMap.Load(typeID); ok { 46 | if err := enc.(encoder)(buf, ptr); err != nil { 47 | return nil, err 48 | } 49 | 50 | // allocate a new buffer required length only 51 | b := make([]byte, len(buf.b)) 52 | copy(b, buf.b) 53 | return b, nil 54 | } 55 | 56 | // First time, 57 | // builds a optimized path by type and caches it with typeID. 58 | enc, err := compile(typ) 59 | if err != nil { 60 | return nil, err 61 | } 62 | typeToEncoderMap.Store(typeID, enc) 63 | if err := enc(buf, ptr); err != nil { 64 | return nil, err 65 | } 66 | 67 | // allocate a new buffer required length only 68 | b := make([]byte, len(buf.b)) 69 | copy(b, buf.b) 70 | return b, nil 71 | } 72 | 73 | func compile(typ reflect.Type) (encoder, error) { 74 | switch typ.Kind() { 75 | case reflect.Struct: 76 | return compileStruct(typ) 77 | case reflect.Int: 78 | return compileInt(typ) 79 | } 80 | return nil, errors.New("unsupported type") 81 | } 82 | 83 | func compileStruct(typ reflect.Type) (encoder, error) { 84 | 85 | encoders := []encoder{} 86 | 87 | for i := 0; i < typ.NumField(); i++ { 88 | field := typ.Field(i) 89 | enc, err := compile(field.Type) 90 | if err != nil { 91 | return nil, err 92 | } 93 | offset := field.Offset 94 | encoders = append(encoders, func(buf *buffer, p unsafe.Pointer) error { 95 | return enc(buf, unsafe.Pointer(uintptr(p)+offset)) 96 | }) 97 | } 98 | return func(buf *buffer, p unsafe.Pointer) error { 99 | buf.b = append(buf.b, '{') 100 | for i, enc := range encoders { 101 | if i != 0 { 102 | buf.b = append(buf.b, ' ') 103 | } 104 | if err := enc(buf, p); err != nil { 105 | return err 106 | } 107 | } 108 | buf.b = append(buf.b, '}') 109 | return nil 110 | }, nil 111 | } 112 | 113 | func compileInt(typ reflect.Type) (encoder, error) { 114 | return func(buf *buffer, p unsafe.Pointer) error { 115 | value := *(*int)(p) 116 | buf.b = strconv.AppendInt(buf.b, int64(value), 10) 117 | return nil 118 | }, nil 119 | } 120 | 121 | func Benchmark_Marshal(b *testing.B) { 122 | b.ReportAllocs() 123 | for n := 0; n < b.N; n++ { 124 | bytes, err := Marshal(struct{ I int }{10}) 125 | if err != nil { 126 | b.Fatal(err) 127 | } 128 | if string(bytes) != "{10}" { 129 | b.Fatalf("unexpected error: %s", string(bytes)) 130 | } 131 | bytes2, err := Marshal(struct{ I, J int }{10, 20}) 132 | if err != nil { 133 | b.Fatal(err) 134 | } 135 | if string(bytes2) != "{10 20}" { 136 | b.Fatalf("unexpected error: %s", string(bytes2)) 137 | } 138 | } 139 | } 140 | -------------------------------------------------------------------------------- /benchmark_test.go: -------------------------------------------------------------------------------- 1 | package reflect_test 2 | 3 | import ( 4 | "reflect" 5 | "testing" 6 | 7 | goreflect "github.com/goccy/go-reflect" 8 | ) 9 | 10 | func kindFromReflect(v interface{}) reflect.Kind { 11 | return reflect.TypeOf(v).Kind() 12 | } 13 | 14 | func kindFromGoReflect(v interface{}) goreflect.Kind { 15 | return goreflect.TypeOf(v).Kind() 16 | } 17 | 18 | func f(_ interface{}) {} 19 | 20 | func valueFromReflect(v interface{}) { 21 | f(reflect.ValueOf(v).Elem()) 22 | } 23 | 24 | func valueFromGoReflect(v interface{}) { 25 | f(goreflect.ValueNoEscapeOf(v).Elem()) 26 | } 27 | 28 | func Benchmark_TypeOf_Reflect(b *testing.B) { 29 | b.ReportAllocs() 30 | for n := 0; n < b.N; n++ { 31 | var v struct { 32 | i int 33 | } 34 | kindFromReflect(&v) 35 | } 36 | } 37 | 38 | func Benchmark_TypeOf_GoReflect(b *testing.B) { 39 | b.ReportAllocs() 40 | for n := 0; n < b.N; n++ { 41 | var v struct { 42 | i int 43 | } 44 | kindFromGoReflect(&v) 45 | } 46 | } 47 | 48 | func Benchmark_ValueOf_Reflect(b *testing.B) { 49 | b.ReportAllocs() 50 | for n := 0; n < b.N; n++ { 51 | valueFromReflect(&struct { 52 | I int 53 | F float64 54 | }{I: 10}) 55 | } 56 | } 57 | 58 | func Benchmark_ValueOf_GoReflect(b *testing.B) { 59 | b.ReportAllocs() 60 | for n := 0; n < b.N; n++ { 61 | valueFromGoReflect(&struct { 62 | I int 63 | F float64 64 | }{I: 10}) 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /bridge.go: -------------------------------------------------------------------------------- 1 | package reflect 2 | 3 | import ( 4 | "reflect" 5 | "unsafe" 6 | ) 7 | 8 | func toRT(t Type) reflect.Type { 9 | return type_toType(t) 10 | } 11 | 12 | func toRTs(t []Type) []reflect.Type { 13 | out := make([]reflect.Type, len(t)) 14 | for idx, tt := range t { 15 | out[idx] = toRT(tt) 16 | } 17 | return out 18 | } 19 | 20 | func toT(t reflect.Type) Type { 21 | return (Type)(((*Value)(unsafe.Pointer(&t))).ptr) 22 | } 23 | 24 | func toRV(v Value) reflect.Value { 25 | return *(*reflect.Value)(unsafe.Pointer(&v)) 26 | } 27 | 28 | func toRVs(v []Value) []reflect.Value { 29 | out := make([]reflect.Value, len(v)) 30 | for idx, vv := range v { 31 | out[idx] = toRV(vv) 32 | } 33 | return out 34 | } 35 | 36 | func toV(v reflect.Value) Value { 37 | return *(*Value)(unsafe.Pointer(&v)) 38 | } 39 | 40 | func toVs(v []reflect.Value) []Value { 41 | out := make([]Value, len(v)) 42 | for idx, vv := range v { 43 | out[idx] = toV(vv) 44 | } 45 | return out 46 | } 47 | 48 | func toRSFs(v []StructField) []reflect.StructField { 49 | out := make([]reflect.StructField, len(v)) 50 | for idx, vv := range v { 51 | out[idx] = toRSF(vv) 52 | } 53 | return out 54 | } 55 | 56 | func toRSF(v StructField) reflect.StructField { 57 | return reflect.StructField{ 58 | Name: v.Name, 59 | PkgPath: v.PkgPath, 60 | Type: ToReflectType(v.Type), 61 | Tag: v.Tag, 62 | Offset: v.Offset, 63 | Index: v.Index, 64 | Anonymous: v.Anonymous, 65 | } 66 | } 67 | 68 | func toSF(v reflect.StructField) StructField { 69 | return StructField{ 70 | Name: v.Name, 71 | PkgPath: v.PkgPath, 72 | Type: ToType(v.Type), 73 | Tag: v.Tag, 74 | Offset: v.Offset, 75 | Index: v.Index, 76 | Anonymous: v.Anonymous, 77 | } 78 | } 79 | 80 | func toM(v reflect.Method) Method { 81 | return Method{ 82 | Name: v.Name, 83 | PkgPath: v.PkgPath, 84 | Type: ToType(v.Type), 85 | Func: toV(v.Func), 86 | Index: v.Index, 87 | } 88 | } 89 | 90 | func toRSC(v SelectCase) reflect.SelectCase { 91 | return reflect.SelectCase{ 92 | Dir: v.Dir, 93 | Chan: toRV(v.Chan), 94 | Send: toRV(v.Send), 95 | } 96 | } 97 | 98 | func toRSCs(v []SelectCase) []reflect.SelectCase { 99 | out := make([]reflect.SelectCase, len(v)) 100 | for idx, vv := range v { 101 | out[idx] = toRSC(vv) 102 | } 103 | return out 104 | } 105 | -------------------------------------------------------------------------------- /example_test.go: -------------------------------------------------------------------------------- 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 | 14 | "github.com/goccy/go-reflect" 15 | ) 16 | 17 | func ExampleKind() { 18 | for _, v := range []interface{}{"hi", 42, func() {}} { 19 | switch v := reflect.ValueOf(v); v.Kind() { 20 | case reflect.String: 21 | fmt.Println(v.String()) 22 | case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: 23 | fmt.Println(v.Int()) 24 | default: 25 | fmt.Printf("unhandled kind %s", v.Kind()) 26 | } 27 | } 28 | 29 | // Output: 30 | // hi 31 | // 42 32 | // unhandled kind func 33 | } 34 | 35 | func ExampleMakeFunc() { 36 | // swap is the implementation passed to MakeFunc. 37 | // It must work in terms of reflect.Values so that it is possible 38 | // to write code without knowing beforehand what the types 39 | // will be. 40 | swap := func(in []reflect.Value) []reflect.Value { 41 | return []reflect.Value{in[1], in[0]} 42 | } 43 | 44 | // makeSwap expects fptr to be a pointer to a nil function. 45 | // It sets that pointer to a new function created with MakeFunc. 46 | // When the function is invoked, reflect turns the arguments 47 | // into Values, calls swap, and then turns swap's result slice 48 | // into the values returned by the new function. 49 | makeSwap := func(fptr interface{}) { 50 | // fptr is a pointer to a function. 51 | // Obtain the function value itself (likely nil) as a reflect.Value 52 | // so that we can query its type and then set the value. 53 | fn := reflect.ValueOf(fptr).Elem() 54 | 55 | // Make a function of the right type. 56 | v := reflect.MakeFunc(fn.Type(), swap) 57 | 58 | // Assign it to the value fn represents. 59 | fn.Set(v) 60 | } 61 | 62 | // Make and call a swap function for ints. 63 | var intSwap func(int, int) (int, int) 64 | makeSwap(&intSwap) 65 | fmt.Println(intSwap(0, 1)) 66 | 67 | // Make and call a swap function for float64s. 68 | var floatSwap func(float64, float64) (float64, float64) 69 | makeSwap(&floatSwap) 70 | fmt.Println(floatSwap(2.72, 3.14)) 71 | 72 | // Output: 73 | // 1 0 74 | // 3.14 2.72 75 | } 76 | 77 | func ExampleStructTag() { 78 | type S struct { 79 | F string `species:"gopher" color:"blue"` 80 | } 81 | 82 | s := S{} 83 | st := reflect.TypeOf(s) 84 | field := st.Field(0) 85 | fmt.Println(field.Tag.Get("color"), field.Tag.Get("species")) 86 | 87 | // Output: 88 | // blue gopher 89 | } 90 | 91 | func ExampleStructTag_Lookup() { 92 | type S struct { 93 | F0 string `alias:"field_0"` 94 | F1 string `alias:""` 95 | F2 string 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 | // Output: 112 | // field_0 113 | // (blank) 114 | // (not specified) 115 | } 116 | 117 | func ExampleTypeOf() { 118 | // As interface types are only used for static typing, a 119 | // common idiom to find the reflection Type for an interface 120 | // type Foo is to use a *Foo value. 121 | writerType := reflect.TypeOf((*io.Writer)(nil)).Elem() 122 | 123 | fileType := reflect.TypeOf((*os.File)(nil)) 124 | fmt.Println(fileType.Implements(writerType)) 125 | 126 | // Output: 127 | // true 128 | } 129 | 130 | func ExampleStructOf() { 131 | typ := reflect.StructOf([]reflect.StructField{ 132 | { 133 | Name: "Height", 134 | Type: reflect.TypeOf(float64(0)), 135 | Tag: `json:"height"`, 136 | }, 137 | { 138 | Name: "Age", 139 | Type: reflect.TypeOf(int(0)), 140 | Tag: `json:"age"`, 141 | }, 142 | }) 143 | 144 | v := reflect.New(typ).Elem() 145 | v.Field(0).SetFloat(0.4) 146 | v.Field(1).SetInt(2) 147 | s := v.Addr().Interface() 148 | 149 | w := new(bytes.Buffer) 150 | if err := json.NewEncoder(w).Encode(s); err != nil { 151 | panic(err) 152 | } 153 | 154 | fmt.Printf("value: %+v\n", s) 155 | fmt.Printf("json: %s", w.Bytes()) 156 | 157 | r := bytes.NewReader([]byte(`{"height":1.5,"age":10}`)) 158 | if err := json.NewDecoder(r).Decode(s); err != nil { 159 | panic(err) 160 | } 161 | fmt.Printf("value: %+v\n", s) 162 | 163 | // Output: 164 | // value: &{Height:0.4 Age:2} 165 | // json: {"height":0.4,"age":2} 166 | // value: &{Height:1.5 Age:10} 167 | } 168 | -------------------------------------------------------------------------------- /export_test.go: -------------------------------------------------------------------------------- 1 | package reflect 2 | 3 | type Buffer struct { 4 | buf []byte 5 | } 6 | -------------------------------------------------------------------------------- /go.mod: -------------------------------------------------------------------------------- 1 | module github.com/goccy/go-reflect 2 | 3 | go 1.12 4 | -------------------------------------------------------------------------------- /go.sum: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/goccy/go-reflect/4646ad15ec8afb955a3bfb6af969f007f169f383/go.sum -------------------------------------------------------------------------------- /init.go: -------------------------------------------------------------------------------- 1 | package reflect 2 | 3 | import ( 4 | "fmt" 5 | "unsafe" 6 | ) 7 | 8 | var ( 9 | errTypeOf = "runtime error: failed to get %s type by TypeOf" 10 | errValueOf = "runtime error: failed to get %s value by ValueOf" 11 | ) 12 | 13 | // validateTypeOf validate interface{} layout and Kind. 14 | func validateTypeOf() error { 15 | if TypeOf(true).Kind() != Bool { 16 | return fmt.Errorf(errTypeOf, "bool") 17 | } 18 | if TypeOf(int(1)).Kind() != Int { 19 | return fmt.Errorf(errTypeOf, "int") 20 | } 21 | if TypeOf(int8(1)).Kind() != Int8 { 22 | return fmt.Errorf(errTypeOf, "int8") 23 | } 24 | if TypeOf(int16(1)).Kind() != Int16 { 25 | return fmt.Errorf(errTypeOf, "int16") 26 | } 27 | if TypeOf(int32(1)).Kind() != Int32 { 28 | return fmt.Errorf(errTypeOf, "int32") 29 | } 30 | if TypeOf(int64(1)).Kind() != Int64 { 31 | return fmt.Errorf(errTypeOf, "int64") 32 | } 33 | if TypeOf(uint(1)).Kind() != Uint { 34 | return fmt.Errorf(errTypeOf, "uint") 35 | } 36 | if TypeOf(uint8(1)).Kind() != Uint8 { 37 | return fmt.Errorf(errTypeOf, "uint8") 38 | } 39 | if TypeOf(uint16(1)).Kind() != Uint16 { 40 | return fmt.Errorf(errTypeOf, "uint16") 41 | } 42 | if TypeOf(uint32(1)).Kind() != Uint32 { 43 | return fmt.Errorf(errTypeOf, "uint32") 44 | } 45 | if TypeOf(uint64(1)).Kind() != Uint64 { 46 | return fmt.Errorf(errTypeOf, "uint64") 47 | } 48 | if TypeOf(uintptr(1)).Kind() != Uintptr { 49 | return fmt.Errorf(errTypeOf, "uintptr") 50 | } 51 | if TypeOf(float32(1)).Kind() != Float32 { 52 | return fmt.Errorf(errTypeOf, "float32") 53 | } 54 | if TypeOf(float64(1)).Kind() != Float64 { 55 | return fmt.Errorf(errTypeOf, "float64") 56 | } 57 | if TypeOf([1]int{1}).Kind() != Array { 58 | return fmt.Errorf(errTypeOf, "array") 59 | } 60 | if TypeOf([]int{1}).Kind() != Slice { 61 | return fmt.Errorf(errTypeOf, "slice") 62 | } 63 | if TypeOf(func() {}).Kind() != Func { 64 | return fmt.Errorf(errTypeOf, "func") 65 | } 66 | if TypeOf(map[struct{}]struct{}{}).Kind() != Map { 67 | return fmt.Errorf(errTypeOf, "map") 68 | } 69 | if TypeOf("").Kind() != String { 70 | return fmt.Errorf(errTypeOf, "string") 71 | } 72 | if TypeOf(struct{}{}).Kind() != Struct { 73 | return fmt.Errorf(errTypeOf, "struct") 74 | } 75 | if TypeOf(&struct{}{}).Kind() != Ptr { 76 | return fmt.Errorf(errTypeOf, "pointer") 77 | } 78 | if TypeOf(unsafe.Pointer(nil)).Kind() != UnsafePointer { 79 | return fmt.Errorf(errTypeOf, "unsafepointer") 80 | } 81 | return nil 82 | } 83 | 84 | // validateValueOf validate value layout and flag values. 85 | func validateValueOf() error { 86 | if v := ValueOf(true); v.Type().Kind() != Bool || v.Bool() != true { 87 | return fmt.Errorf(errValueOf, "bool") 88 | } 89 | if v := ValueOf(int(1)); v.Type().Kind() != Int || v.Int() != 1 { 90 | return fmt.Errorf(errValueOf, "int") 91 | } 92 | if v := ValueOf(int8(1)); v.Type().Kind() != Int8 || v.Int() != 1 { 93 | return fmt.Errorf(errValueOf, "int8") 94 | } 95 | if v := ValueOf(int16(1)); v.Type().Kind() != Int16 || v.Int() != 1 { 96 | return fmt.Errorf(errValueOf, "int16") 97 | } 98 | if v := ValueOf(int32(1)); v.Type().Kind() != Int32 || v.Int() != 1 { 99 | return fmt.Errorf(errValueOf, "int32") 100 | } 101 | if v := ValueOf(int64(1)); v.Type().Kind() != Int64 || v.Int() != 1 { 102 | return fmt.Errorf(errValueOf, "int64") 103 | } 104 | if v := ValueOf(uint(1)); v.Type().Kind() != Uint || v.Uint() != 1 { 105 | return fmt.Errorf(errValueOf, "uint") 106 | } 107 | if v := ValueOf(uint8(1)); v.Type().Kind() != Uint8 || v.Uint() != 1 { 108 | return fmt.Errorf(errValueOf, "uint8") 109 | } 110 | if v := ValueOf(uint16(1)); v.Type().Kind() != Uint16 || v.Uint() != 1 { 111 | return fmt.Errorf(errValueOf, "uint16") 112 | } 113 | if v := ValueOf(uint32(1)); v.Type().Kind() != Uint32 || v.Uint() != 1 { 114 | return fmt.Errorf(errValueOf, "uint32") 115 | } 116 | if v := ValueOf(uint64(1)); v.Type().Kind() != Uint64 || v.Uint() != 1 { 117 | return fmt.Errorf(errValueOf, "uint64") 118 | } 119 | if v := ValueOf(uintptr(1)); v.Type().Kind() != Uintptr || v.Uint() != 1 { 120 | return fmt.Errorf(errValueOf, "uintptr") 121 | } 122 | if v := ValueOf(float32(1)); v.Type().Kind() != Float32 || v.Float() != 1 { 123 | return fmt.Errorf(errValueOf, "float32") 124 | } 125 | if v := ValueOf(float64(1)); v.Type().Kind() != Float64 || v.Float() != 1 { 126 | return fmt.Errorf(errValueOf, "float64") 127 | } 128 | if v := ValueOf([1]int{1}); v.Type().Kind() != Array || v.Len() != 1 { 129 | return fmt.Errorf(errValueOf, "array") 130 | } 131 | if v := ValueOf([]int{1}); v.Type().Kind() != Slice || v.Len() != 1 { 132 | return fmt.Errorf(errValueOf, "slice") 133 | } 134 | if v := ValueOf(func() {}); v.Type().Kind() != Func { 135 | return fmt.Errorf(errValueOf, "func") 136 | } 137 | if v := ValueOf(map[struct{}]struct{}{}); v.Type().Kind() != Map { 138 | return fmt.Errorf(errValueOf, "map") 139 | } 140 | if v := ValueOf("1"); v.Type().Kind() != String || v.String() != "1" { 141 | return fmt.Errorf(errValueOf, "string") 142 | } 143 | if v := ValueOf(struct{}{}); v.Type().Kind() != Struct { 144 | return fmt.Errorf(errValueOf, "struct") 145 | } 146 | if v := ValueOf(&struct{}{}); v.Type().Kind() != Ptr { 147 | return fmt.Errorf(errValueOf, "pointer") 148 | } 149 | if v := ValueOf(unsafe.Pointer(nil)); v.Type().Kind() != UnsafePointer { 150 | return fmt.Errorf(errValueOf, "unsafepointer") 151 | } 152 | return nil 153 | } 154 | 155 | func validate() error { 156 | if err := validateTypeOf(); err != nil { 157 | return err 158 | } 159 | if err := validateValueOf(); err != nil { 160 | return err 161 | } 162 | return nil 163 | } 164 | 165 | func init() { 166 | if err := validate(); err != nil { 167 | panic(err) 168 | } 169 | } 170 | -------------------------------------------------------------------------------- /reflect.go: -------------------------------------------------------------------------------- 1 | package reflect 2 | 3 | import ( 4 | "reflect" 5 | "unsafe" 6 | ) 7 | 8 | // Type is the representation of a Go type. 9 | // 10 | // Not all methods apply to all kinds of types. Restrictions, 11 | // if any, are noted in the documentation for each method. 12 | // Use the Kind method to find out the kind of type before 13 | // calling kind-specific methods. Calling a method 14 | // inappropriate to the kind of type causes a run-time panic. 15 | // 16 | // Type values are comparable, such as with the == operator, 17 | // so they can be used as map keys. 18 | // Two Type values are equal if they represent identical types. 19 | type Type = *rtype 20 | 21 | type rtype struct{} 22 | 23 | type flag uintptr 24 | 25 | const ( 26 | flagKindWidth = 5 // there are 27 kinds 27 | flagKindMask flag = 1<", and all other methods panic. 154 | // Most functions and methods never return an invalid value. 155 | // If one does, its documentation states the conditions explicitly. 156 | // A Value can be used concurrently by multiple goroutines provided that 157 | // the underlying Go value can be used concurrently for the equivalent direct operations. 158 | // To compare two Values, compare the results of the Interface method. 159 | // Using == on two Values does not compare the underlying values they represent. 160 | type Value struct { 161 | typ Type 162 | ptr unsafe.Pointer 163 | flag 164 | } 165 | 166 | // Method represents a single method. 167 | type Method struct { 168 | // Name is the method name. 169 | // PkgPath is the package path that qualifies a lower case (unexported) 170 | // method name. It is empty for upper case (exported) method names. 171 | // The combination of PkgPath and Name uniquely identifies a method 172 | // in a method set. 173 | // See https://golang.org/ref/spec#Uniqueness_of_identifiers 174 | Name string 175 | PkgPath string 176 | 177 | Type Type // method type 178 | Func Value // func with receiver as first argument 179 | Index int // index for Type.Method 180 | } 181 | 182 | // A StructField describes a single field in a struct. 183 | type StructField struct { 184 | // Name is the field name. 185 | Name string 186 | // PkgPath is the package path that qualifies a lower case (unexported) 187 | // field name. It is empty for upper case (exported) field names. 188 | // See https://golang.org/ref/spec#Uniqueness_of_identifiers 189 | PkgPath string 190 | 191 | Type Type // field type 192 | Tag StructTag // field tag string 193 | Offset uintptr // offset within struct, in bytes 194 | Index []int // index sequence for Type.FieldByIndex 195 | Anonymous bool // is an embedded field 196 | } 197 | 198 | // IsExported reports whether the field is exported. 199 | func (f StructField) IsExported() bool { 200 | return f.PkgPath == "" 201 | } 202 | 203 | // ArrayOf returns the array type with the given count and element type. 204 | // For example, if t represents int, ArrayOf(5, t) represents [5]int. 205 | // 206 | // If the resulting type would be larger than the available address space, 207 | // ArrayOf panics. 208 | func ArrayOf(count int, elem Type) Type { 209 | return arrayOf(count, elem) 210 | } 211 | 212 | // ChanOf returns the channel type with the given direction and element type. 213 | // For example, if t represents int, ChanOf(RecvDir, t) represents <-chan int. 214 | // 215 | // The gc runtime imposes a limit of 64 kB on channel element types. 216 | // If t's size is equal to or exceeds this limit, ChanOf panics. 217 | func ChanOf(dir ChanDir, t Type) Type { 218 | return chanOf(dir, t) 219 | } 220 | 221 | // FuncOf returns the function type with the given argument and result types. 222 | // For example if k represents int and e represents string, 223 | // FuncOf([]Type{k}, []Type{e}, false) represents func(int) string. 224 | // 225 | // The variadic argument controls whether the function is variadic. FuncOf 226 | // panics if the in[len(in)-1] does not represent a slice and variadic is 227 | // true. 228 | func FuncOf(in, out []Type, variadic bool) Type { 229 | return funcOf(in, out, variadic) 230 | } 231 | 232 | // MapOf returns the map type with the given key and element types. 233 | // For example, if k represents int and e represents string, 234 | // MapOf(k, e) represents map[int]string. 235 | // 236 | // If the key type is not a valid map key type (that is, if it does 237 | // not implement Go's == operator), MapOf panics. 238 | func MapOf(key, elem Type) Type { 239 | return mapOf(key, elem) 240 | } 241 | 242 | // PtrTo returns the pointer type with element t. 243 | // For example, if t represents type Foo, PtrTo(t) represents *Foo. 244 | func PtrTo(t Type) Type { 245 | return ptrTo(t) 246 | } 247 | 248 | // SliceOf returns the slice type with element type t. 249 | // For example, if t represents int, SliceOf(t) represents []int. 250 | func SliceOf(t Type) Type { 251 | return sliceOf(t) 252 | } 253 | 254 | // StructOf returns the struct type containing fields. 255 | // The Offset and Index fields are ignored and computed as they would be 256 | // by the compiler. 257 | // 258 | // StructOf currently does not generate wrapper methods for embedded 259 | // fields and panics if passed unexported StructFields. 260 | // These limitations may be lifted in a future version. 261 | func StructOf(fields []StructField) Type { 262 | return structOf(fields) 263 | } 264 | 265 | // TypeOf returns the reflection Type that represents the dynamic type of i. 266 | // If i is a nil interface value, TypeOf returns nil. 267 | func TypeOf(v interface{}) Type { 268 | value := (*Value)(unsafe.Pointer(&v)) 269 | return value.typ 270 | } 271 | 272 | // TypeID returns unique type identifier of v. 273 | func TypeID(v interface{}) uintptr { 274 | return uintptr(unsafe.Pointer(TypeOf(v))) 275 | } 276 | 277 | func valueOf(v interface{}) Value { 278 | if v == nil { 279 | return Value{} 280 | } 281 | valueLayout := (*Value)(unsafe.Pointer(&v)) 282 | value := Value{} 283 | value.typ = valueLayout.typ 284 | value.ptr = valueLayout.ptr 285 | f := flag(value.typ.Kind()) 286 | if ifaceIndir(value.typ) { 287 | f |= flagIndir 288 | } 289 | value.flag = f 290 | return value 291 | } 292 | 293 | // TypeAndPtrOf returns raw Type and ptr value in favor of performance. 294 | func TypeAndPtrOf(v interface{}) (Type, unsafe.Pointer) { 295 | value := (*Value)(unsafe.Pointer(&v)) 296 | return value.typ, value.ptr 297 | } 298 | 299 | // ValueOf returns a new Value initialized to the concrete value 300 | // stored in the interface i. ValueOf(nil) returns the zero Value. 301 | func ValueOf(v interface{}) Value { 302 | escape(v) 303 | return valueOf(v) 304 | } 305 | 306 | // ValueNoEscapeOf no escape of ValueOf. 307 | func ValueNoEscapeOf(v interface{}) Value { 308 | return valueOf(v) 309 | } 310 | 311 | // ToReflectType convert Type to reflect.Type 312 | func ToReflectType(t Type) reflect.Type { 313 | return toRT(t) 314 | } 315 | 316 | // ToReflectValue convert Value to reflect.Value 317 | func ToReflectValue(v Value) reflect.Value { 318 | return toRV(v) 319 | } 320 | 321 | // ToType convert reflect.Type to Type 322 | func ToType(t reflect.Type) Type { 323 | return toT(t) 324 | } 325 | 326 | // ToValue convert reflect.Value to Value 327 | func ToValue(v reflect.Value) Value { 328 | return toV(v) 329 | } 330 | 331 | // Copy copies the contents of src into dst until either 332 | // dst has been filled or src has been exhausted. 333 | // It returns the number of elements copied. 334 | // Dst and src each must have kind Slice or Array, and 335 | // dst and src must have the same element type. 336 | // 337 | // As a special case, src can have kind String if the element type of dst is kind Uint8. 338 | func Copy(dst, src Value) int { 339 | return value_Copy(dst, src) 340 | } 341 | 342 | // DeepEqual reports whether x and y are “deeply equal,” defined as follows. 343 | // Two values of identical type are deeply equal if one of the following cases applies. 344 | // Values of distinct types are never deeply equal. 345 | // 346 | // Array values are deeply equal when their corresponding elements are deeply equal. 347 | // 348 | // Struct values are deeply equal if their corresponding fields, 349 | // both exported and unexported, are deeply equal. 350 | // 351 | // Func values are deeply equal if both are nil; otherwise they are not deeply equal. 352 | // 353 | // Interface values are deeply equal if they hold deeply equal concrete values. 354 | // 355 | // Map values are deeply equal when all of the following are true: 356 | // they are both nil or both non-nil, they have the same length, 357 | // and either they are the same map object or their corresponding keys 358 | // (matched using Go equality) map to deeply equal values. 359 | // 360 | // Pointer values are deeply equal if they are equal using Go's == operator 361 | // or if they point to deeply equal values. 362 | // 363 | // Slice values are deeply equal when all of the following are true: 364 | // they are both nil or both non-nil, they have the same length, 365 | // and either they point to the same initial entry of the same underlying array 366 | // (that is, &x[0] == &y[0]) or their corresponding elements (up to length) are deeply equal. 367 | // Note that a non-nil empty slice and a nil slice (for example, []byte{} and []byte(nil)) 368 | // are not deeply equal. 369 | // 370 | // Other values - numbers, bools, strings, and channels - are deeply equal 371 | // if they are equal using Go's == operator. 372 | // 373 | // In general DeepEqual is a recursive relaxation of Go's == operator. 374 | // However, this idea is impossible to implement without some inconsistency. 375 | // Specifically, it is possible for a value to be unequal to itself, 376 | // either because it is of func type (uncomparable in general) 377 | // or because it is a floating-point NaN value (not equal to itself in floating-point comparison), 378 | // or because it is an array, struct, or interface containing 379 | // such a value. 380 | // On the other hand, pointer values are always equal to themselves, 381 | // even if they point at or contain such problematic values, 382 | // because they compare equal using Go's == operator, and that 383 | // is a sufficient condition to be deeply equal, regardless of content. 384 | // DeepEqual has been defined so that the same short-cut applies 385 | // to slices and maps: if x and y are the same slice or the same map, 386 | // they are deeply equal regardless of content. 387 | // 388 | // As DeepEqual traverses the data values it may find a cycle. The 389 | // second and subsequent times that DeepEqual compares two pointer 390 | // values that have been compared before, it treats the values as 391 | // equal rather than examining the values to which they point. 392 | // This ensures that DeepEqual terminates. 393 | func DeepEqual(x, y interface{}) bool { 394 | return reflect.DeepEqual(x, y) 395 | } 396 | 397 | func Swapper(slice interface{}) func(i, j int) { 398 | return reflect.Swapper(slice) 399 | } 400 | 401 | // Append appends the values x to a slice s and returns the resulting slice. 402 | // As in Go, each x's value must be assignable to the slice's element type. 403 | func Append(s Value, x ...Value) Value { 404 | return value_Append(s, x...) 405 | } 406 | 407 | // AppendSlice appends a slice t to a slice s and returns the resulting slice. 408 | // The slices s and t must have the same element type. 409 | func AppendSlice(s, t Value) Value { 410 | return value_AppendSlice(s, t) 411 | } 412 | 413 | // Indirect returns the value that v points to. 414 | // If v is a nil pointer, Indirect returns a zero Value. 415 | // If v is not a pointer, Indirect returns v. 416 | func Indirect(v Value) Value { 417 | return value_Indirect(v) 418 | } 419 | 420 | // MakeChan creates a new channel with the specified type and buffer size. 421 | func MakeChan(typ Type, buffer int) Value { 422 | return value_MakeChan(typ, buffer) 423 | } 424 | 425 | // MakeFunc returns a new function of the given Type 426 | // that wraps the function fn. When called, that new function 427 | // does the following: 428 | // 429 | // - converts its arguments to a slice of Values. 430 | // - runs results := fn(args). 431 | // - returns the results as a slice of Values, one per formal result. 432 | // 433 | // The implementation fn can assume that the argument Value slice 434 | // has the number and type of arguments given by typ. 435 | // If typ describes a variadic function, the final Value is itself 436 | // a slice representing the variadic arguments, as in the 437 | // body of a variadic function. The result Value slice returned by fn 438 | // must have the number and type of results given by typ. 439 | // 440 | // The Value.Call method allows the caller to invoke a typed function 441 | // in terms of Values; in contrast, MakeFunc allows the caller to implement 442 | // a typed function in terms of Values. 443 | // 444 | // The Examples section of the documentation includes an illustration 445 | // of how to use MakeFunc to build a swap function for different types. 446 | func MakeFunc(typ Type, fn func(args []Value) (results []Value)) Value { 447 | return value_MakeFunc(typ, fn) 448 | } 449 | 450 | // MakeMap creates a new map with the specified type. 451 | func MakeMap(typ Type) Value { 452 | return value_MakeMap(typ) 453 | } 454 | 455 | // MakeMapWithSize creates a new map with the specified type 456 | // and initial space for approximately n elements. 457 | func MakeMapWithSize(typ Type, n int) Value { 458 | return value_MakeMapWithSize(typ, n) 459 | } 460 | 461 | // MakeSlice creates a new zero-initialized slice value 462 | // for the specified slice type, length, and capacity. 463 | func MakeSlice(typ Type, len, cap int) Value { 464 | return value_MakeSlice(typ, len, cap) 465 | } 466 | 467 | // New returns a Value representing a pointer to a new zero value 468 | // for the specified type. That is, the returned Value's Type is PtrTo(typ). 469 | func New(typ Type) Value { 470 | return value_New(typ) 471 | } 472 | 473 | // NewAt returns a Value representing a pointer to a value of the 474 | // specified type, using p as that pointer. 475 | func NewAt(typ Type, p unsafe.Pointer) Value { 476 | return value_NewAt(typ, p) 477 | } 478 | 479 | // Select executes a select operation described by the list of cases. 480 | // Like the Go select statement, it blocks until at least one of the cases 481 | // can proceed, makes a uniform pseudo-random choice, 482 | // and then executes that case. It returns the index of the chosen case 483 | // and, if that case was a receive operation, the value received and a 484 | // boolean indicating whether the value corresponds to a send on the channel 485 | // (as opposed to a zero value received because the channel is closed). 486 | func Select(cases []SelectCase) (int, Value, bool) { 487 | return value_Select(cases) 488 | } 489 | 490 | // Zero returns a Value representing the zero value for the specified type. 491 | // The result is different from the zero value of the Value struct, 492 | // which represents no value at all. 493 | // For example, Zero(TypeOf(42)) returns a Value with Kind Int and value 0. 494 | // The returned value is neither addressable nor settable. 495 | func Zero(typ Type) Value { 496 | return value_Zero(typ) 497 | } 498 | 499 | // Align returns the alignment in bytes of a value of 500 | // this type when allocated in memory. 501 | func (t *rtype) Align() int { 502 | return type_Align(t) 503 | } 504 | 505 | // FieldAlign returns the alignment in bytes of a value of 506 | // this type when used as a field in a struct. 507 | func (t *rtype) FieldAlign() int { 508 | return type_FieldAlign(t) 509 | } 510 | 511 | // Method returns the i'th method in the type's method set. 512 | // It panics if i is not in the range [0, NumMethod()). 513 | // 514 | // For a non-interface type T or *T, the returned Method's Type and Func 515 | // fields describe a function whose first argument is the receiver. 516 | // 517 | // For an interface type, the returned Method's Type field gives the 518 | // method signature, without a receiver, and the Func field is nil. 519 | // 520 | // Only exported methods are accessible and they are sorted in 521 | // lexicographic order. 522 | func (t *rtype) Method(a0 int) Method { 523 | return toM(type_Method(t, a0)) 524 | } 525 | 526 | // MethodByName returns the method with that name in the type's 527 | // method set and a boolean indicating if the method was found. 528 | // 529 | // For a non-interface type T or *T, the returned Method's Type and Func 530 | // fields describe a function whose first argument is the receiver. 531 | // 532 | // For an interface type, the returned Method's Type field gives the 533 | // method signature, without a receiver, and the Func field is nil. 534 | func (t *rtype) MethodByName(a0 string) (Method, bool) { 535 | mtd, ok := type_MethodByName(t, a0) 536 | return toM(mtd), ok 537 | } 538 | 539 | // NumMethod returns the number of exported methods in the type's method set. 540 | func (t *rtype) NumMethod() int { 541 | return type_NumMethod(t) 542 | } 543 | 544 | // Name returns the type's name within its package for a defined type. 545 | // For other (non-defined) types it returns the empty string. 546 | func (t *rtype) Name() string { 547 | return type_Name(t) 548 | } 549 | 550 | // PkgPath returns a defined type's package path, that is, the import path 551 | // that uniquely identifies the package, such as "encoding/base64". 552 | // If the type was predeclared (string, error) or not defined (*T, struct{}, 553 | // []int, or A where A is an alias for a non-defined type), the package path 554 | // will be the empty string. 555 | func (t *rtype) PkgPath() string { 556 | return type_PkgPath(t) 557 | } 558 | 559 | // Size returns the number of bytes needed to store 560 | // a value of the given type; it is analogous to unsafe.Sizeof. 561 | func (t *rtype) Size() uintptr { 562 | return type_Size(t) 563 | } 564 | 565 | // String returns a string representation of the type. 566 | // The string representation may use shortened package names 567 | // (e.g., base64 instead of "encoding/base64") and is not 568 | // guaranteed to be unique among types. To test for type identity, 569 | // compare the Types directly. 570 | func (t *rtype) String() string { 571 | return type_String(t) 572 | } 573 | 574 | // Kind returns the specific kind of this type. 575 | func (t *rtype) Kind() Kind { 576 | return type_Kind(t) 577 | } 578 | 579 | // Implements reports whether the type implements the interface type u. 580 | func (t *rtype) Implements(u Type) bool { 581 | return type_Implements(t, toRT(u)) 582 | } 583 | 584 | // AssignableTo reports whether a value of the type is assignable to type u. 585 | func (t *rtype) AssignableTo(u Type) bool { 586 | return type_AssignableTo(t, toRT(u)) 587 | } 588 | 589 | // ConvertibleTo reports whether a value of the type is convertible to type u. 590 | func (t *rtype) ConvertibleTo(u Type) bool { 591 | return type_ConvertibleTo(t, toRT(u)) 592 | } 593 | 594 | // Comparable reports whether values of this type are comparable. 595 | func (t *rtype) Comparable() bool { 596 | return type_Comparable(t) 597 | } 598 | 599 | // Methods applicable only to some types, depending on Kind. 600 | // The methods allowed for each kind are: 601 | // 602 | // Int*, Uint*, Float*, Complex*: Bits 603 | // Array: Elem, Len 604 | // Chan: ChanDir, Elem 605 | // Func: In, NumIn, Out, NumOut, IsVariadic. 606 | // Map: Key, Elem 607 | // Ptr: Elem 608 | // Slice: Elem 609 | // Struct: Field, FieldByIndex, FieldByName, FieldByNameFunc, NumField 610 | 611 | // Bits returns the size of the type in bits. 612 | // It panics if the type's Kind is not one of the 613 | // sized or unsized Int, Uint, Float, or Complex kinds. 614 | func (t *rtype) Bits() int { 615 | return type_Bits(t) 616 | } 617 | 618 | // ChanDir returns a channel type's direction. 619 | // It panics if the type's Kind is not Chan. 620 | func (t *rtype) ChanDir() ChanDir { 621 | return type_ChanDir(t) 622 | } 623 | 624 | // IsVariadic reports whether a function type's final input parameter 625 | // is a "..." parameter. If so, t.In(t.NumIn() - 1) returns the parameter's 626 | // implicit actual type []T. 627 | // 628 | // For concreteness, if t represents func(x int, y ... float64), then 629 | // 630 | // t.NumIn() == 2 631 | // t.In(0) is the reflect.Type for "int" 632 | // t.In(1) is the reflect.Type for "[]float64" 633 | // t.IsVariadic() == true 634 | // 635 | // IsVariadic panics if the type's Kind is not Func. 636 | func (t *rtype) IsVariadic() bool { 637 | return type_IsVariadic(t) 638 | } 639 | 640 | // Elem returns a type's element type. 641 | // It panics if the type's Kind is not Array, Chan, Map, Ptr, or Slice. 642 | func (t *rtype) Elem() Type { 643 | return ToType(type_Elem(t)) 644 | } 645 | 646 | // Field returns a struct type's i'th field. 647 | // It panics if the type's Kind is not Struct. 648 | // It panics if i is not in the range [0, NumField()). 649 | func (t *rtype) Field(i int) StructField { 650 | return toSF(type_Field(t, i)) 651 | } 652 | 653 | // FieldByIndex returns the nested field corresponding 654 | // to the index sequence. It is equivalent to calling Field 655 | // successively for each index i. 656 | // It panics if the type's Kind is not Struct. 657 | func (t *rtype) FieldByIndex(index []int) StructField { 658 | return toSF(type_FieldByIndex(t, index)) 659 | } 660 | 661 | // FieldByName returns the struct field with the given name 662 | // and a boolean indicating if the field was found. 663 | func (t *rtype) FieldByName(name string) (StructField, bool) { 664 | field, ok := type_FieldByName(t, name) 665 | return toSF(field), ok 666 | } 667 | 668 | // FieldByNameFunc returns the struct field with a name 669 | // that satisfies the match function and a boolean indicating if 670 | // the field was found. 671 | // 672 | // FieldByNameFunc considers the fields in the struct itself 673 | // and then the fields in any embedded structs, in breadth first order, 674 | // stopping at the shallowest nesting depth containing one or more 675 | // fields satisfying the match function. If multiple fields at that depth 676 | // satisfy the match function, they cancel each other 677 | // and FieldByNameFunc returns no match. 678 | // This behavior mirrors Go's handling of name lookup in 679 | // structs containing embedded fields. 680 | func (t *rtype) FieldByNameFunc(match func(string) bool) (StructField, bool) { 681 | field, ok := type_FieldByNameFunc(t, match) 682 | return toSF(field), ok 683 | } 684 | 685 | // In returns the type of a function type's i'th input parameter. 686 | // It panics if the type's Kind is not Func. 687 | // It panics if i is not in the range [0, NumIn()). 688 | func (t *rtype) In(i int) Type { 689 | return ToType(type_In(t, i)) 690 | } 691 | 692 | // Key returns a map type's key type. 693 | // It panics if the type's Kind is not Map. 694 | func (t *rtype) Key() Type { 695 | return ToType(type_Key(t)) 696 | } 697 | 698 | // Len returns an array type's length. 699 | // It panics if the type's Kind is not Array. 700 | func (t *rtype) Len() int { 701 | return type_Len(t) 702 | } 703 | 704 | // NumField returns a struct type's field count. 705 | // It panics if the type's Kind is not Struct. 706 | func (t *rtype) NumField() int { 707 | return type_NumField(t) 708 | } 709 | 710 | // NumIn returns a function type's input parameter count. 711 | // It panics if the type's Kind is not Func. 712 | func (t *rtype) NumIn() int { 713 | return type_NumIn(t) 714 | } 715 | 716 | // NumOut returns a function type's output parameter count. 717 | // It panics if the type's Kind is not Func. 718 | func (t *rtype) NumOut() int { 719 | return type_NumOut(t) 720 | } 721 | 722 | // Out returns the type of a function type's i'th output parameter. 723 | // It panics if the type's Kind is not Func. 724 | // It panics if i is not in the range [0, NumOut()). 725 | func (t *rtype) Out(i int) Type { 726 | return toT(type_Out(t, i)) 727 | } 728 | 729 | // Addr returns a pointer value representing the address of v. 730 | // It panics if CanAddr() returns false. 731 | // Addr is typically used to obtain a pointer to a struct field 732 | // or slice element in order to call a method that requires a 733 | // pointer receiver. 734 | func (v Value) Addr() Value { 735 | return value_Addr(v) 736 | } 737 | 738 | // Bool returns v's underlying value. 739 | // It panics if v's kind is not Bool. 740 | func (v Value) Bool() bool { 741 | return value_Bool(v) 742 | } 743 | 744 | // Bytes returns v's underlying value. 745 | // It panics if v's underlying value is not a slice of bytes. 746 | func (v Value) Bytes() []byte { 747 | return value_Bytes(v) 748 | } 749 | 750 | // Call calls the function v with the input arguments in. 751 | // For example, if len(in) == 3, v.Call(in) represents the Go call v(in[0], in[1], in[2]). 752 | // Call panics if v's Kind is not Func. 753 | // It returns the output results as Values. 754 | // As in Go, each input argument must be assignable to the 755 | // type of the function's corresponding input parameter. 756 | // If v is a variadic function, Call creates the variadic slice parameter 757 | // itself, copying in the corresponding values. 758 | func (v Value) Call(in []Value) []Value { 759 | return value_Call(v, in) 760 | } 761 | 762 | // CallSlice calls the variadic function v with the input arguments in, 763 | // assigning the slice in[len(in)-1] to v's final variadic argument. 764 | // For example, if len(in) == 3, v.CallSlice(in) represents the Go call v(in[0], in[1], in[2]...). 765 | // CallSlice panics if v's Kind is not Func or if v is not variadic. 766 | // It returns the output results as Values. 767 | // As in Go, each input argument must be assignable to the 768 | // type of the function's corresponding input parameter. 769 | func (v Value) CallSlice(in []Value) []Value { 770 | return value_CallSlice(v, in) 771 | } 772 | 773 | // CanAddr reports whether the value's address can be obtained with Addr. 774 | // Such values are called addressable. A value is addressable if it is 775 | // an element of a slice, an element of an addressable array, 776 | // a field of an addressable struct, or the result of dereferencing a pointer. 777 | // If CanAddr returns false, calling Addr will panic. 778 | func (v Value) CanAddr() bool { 779 | return value_CanAddr(v) 780 | } 781 | 782 | // CanInterface reports whether Interface can be used without panicking. 783 | func (v Value) CanInterface() bool { 784 | return value_CanInterface(v) 785 | } 786 | 787 | // CanSet reports whether the value of v can be changed. 788 | // A Value can be changed only if it is addressable and was not 789 | // obtained by the use of unexported struct fields. 790 | // If CanSet returns false, calling Set or any type-specific 791 | // setter (e.g., SetBool, SetInt) will panic. 792 | func (v Value) CanSet() bool { 793 | return value_CanSet(v) 794 | } 795 | 796 | // Cap returns v's capacity. 797 | // It panics if v's Kind is not Array, Chan, or Slice. 798 | func (v Value) Cap() int { 799 | return value_Cap(v) 800 | } 801 | 802 | // Close closes the channel v. 803 | // It panics if v's Kind is not Chan. 804 | func (v Value) Close() { 805 | value_Close(v) 806 | } 807 | 808 | // Complex returns v's underlying value, as a complex128. 809 | // It panics if v's Kind is not Complex64 or Complex128. 810 | func (v Value) Complex() complex128 { 811 | return value_Complex(v) 812 | } 813 | 814 | // Convert returns the value v converted to type t. 815 | // If the usual Go conversion rules do not allow conversion 816 | // of the value v to type t, Convert panics. 817 | func (v Value) Convert(t Type) Value { 818 | return value_Convert(v, t) 819 | } 820 | 821 | // Elem returns the value that the interface v contains 822 | // or that the pointer v points to. 823 | // It panics if v's Kind is not Interface or Ptr. 824 | // It returns the zero Value if v is nil. 825 | func (v Value) Elem() Value { 826 | return value_Elem(v) 827 | } 828 | 829 | // Field returns the i'th field of the struct v. 830 | // It panics if v's Kind is not Struct or i is out of range. 831 | func (v Value) Field(i int) Value { 832 | return value_Field(v, i) 833 | } 834 | 835 | // FieldByIndex returns the nested field corresponding to index. 836 | // It panics if v's Kind is not struct. 837 | func (v Value) FieldByIndex(index []int) Value { 838 | return value_FieldByIndex(v, index) 839 | } 840 | 841 | // FieldByName returns the struct field with the given name. 842 | // It returns the zero Value if no field was found. 843 | // It panics if v's Kind is not struct. 844 | func (v Value) FieldByName(name string) Value { 845 | return value_FieldByName(v, name) 846 | } 847 | 848 | // FieldByNameFunc returns the struct field with a name 849 | // that satisfies the match function. 850 | // It panics if v's Kind is not struct. 851 | // It returns the zero Value if no field was found. 852 | func (v Value) FieldByNameFunc(match func(string) bool) Value { 853 | return value_FieldByNameFunc(v, match) 854 | } 855 | 856 | // Float returns v's underlying value, as a float64. 857 | // It panics if v's Kind is not Float32 or Float64. 858 | func (v Value) Float() float64 { 859 | return value_Float(v) 860 | } 861 | 862 | // Index returns v's i'th element. 863 | // It panics if v's Kind is not Array, Slice, or String or i is out of range. 864 | func (v Value) Index(i int) Value { 865 | return value_Index(v, i) 866 | } 867 | 868 | // Int returns v's underlying value, as an int64. 869 | // It panics if v's Kind is not Int, Int8, Int16, Int32, or Int64. 870 | func (v Value) Int() int64 { 871 | return value_Int(v) 872 | } 873 | 874 | // Interface returns v's current value as an interface{}. 875 | // It is equivalent to: 876 | // 877 | // var i interface{} = (v's underlying value) 878 | // 879 | // It panics if the Value was obtained by accessing 880 | // unexported struct fields. 881 | func (v Value) Interface() interface{} { 882 | return value_Interface(v) 883 | } 884 | 885 | // InterfaceData returns the interface v's value as a uintptr pair. 886 | // It panics if v's Kind is not Interface. 887 | func (v Value) InterfaceData() [2]uintptr { 888 | return value_InterfaceData(v) 889 | } 890 | 891 | // IsNil reports whether its argument v is nil. The argument must be 892 | // a chan, func, interface, map, pointer, or slice value; if it is 893 | // not, IsNil panics. Note that IsNil is not always equivalent to a 894 | // regular comparison with nil in Go. For example, if v was created 895 | // by calling ValueOf with an uninitialized interface variable i, 896 | // i==nil will be true but v.IsNil will panic as v will be the zero 897 | // Value. 898 | func (v Value) IsNil() bool { 899 | return value_IsNil(v) 900 | } 901 | 902 | // IsValid reports whether v represents a value. 903 | // It returns false if v is the zero Value. 904 | // If IsValid returns false, all other methods except String panic. 905 | // Most functions and methods never return an invalid Value. 906 | // If one does, its documentation states the conditions explicitly. 907 | func (v Value) IsValid() bool { 908 | return value_IsValid(v) 909 | } 910 | 911 | // Kind returns v's Kind. 912 | // If v is the zero Value (IsValid returns false), Kind returns Invalid. 913 | func (v Value) Kind() Kind { 914 | return value_Kind(v) 915 | } 916 | 917 | // Len returns v's length. 918 | // It panics if v's Kind is not Array, Chan, Map, Slice, or String. 919 | func (v Value) Len() int { 920 | return value_Len(v) 921 | } 922 | 923 | // MapIndex returns the value associated with key in the map v. 924 | // It panics if v's Kind is not Map. 925 | // It returns the zero Value if key is not found in the map or if v represents a nil map. 926 | // As in Go, the key's value must be assignable to the map's key type. 927 | func (v Value) MapIndex(key Value) Value { 928 | return value_MapIndex(v, key) 929 | } 930 | 931 | // MapKeys returns a slice containing all the keys present in the map, 932 | // in unspecified order. 933 | // It panics if v's Kind is not Map. 934 | // It returns an empty slice if v represents a nil map. 935 | func (v Value) MapKeys() []Value { 936 | return value_MapKeys(v) 937 | } 938 | 939 | // MapRange returns a range iterator for a map. 940 | // It panics if v's Kind is not Map. 941 | // 942 | // Call Next to advance the iterator, and Key/Value to access each entry. 943 | // Next returns false when the iterator is exhausted. 944 | // MapRange follows the same iteration semantics as a range statement. 945 | // 946 | // Example: 947 | // 948 | // iter := reflect.ValueOf(m).MapRange() 949 | // for iter.Next() { 950 | // k := iter.Key() 951 | // v := iter.Value() 952 | // ... 953 | // } 954 | func (v Value) MapRange() *MapIter { 955 | return value_MapRange(v) 956 | } 957 | 958 | // Method returns a function value corresponding to v's i'th method. 959 | // The arguments to a Call on the returned function should not include 960 | // a receiver; the returned function will always use v as the receiver. 961 | // Method panics if i is out of range or if v is a nil interface value. 962 | func (v Value) Method(i int) Value { 963 | return value_Method(v, i) 964 | } 965 | 966 | // MethodByName returns a function value corresponding to the method 967 | // of v with the given name. 968 | // The arguments to a Call on the returned function should not include 969 | // a receiver; the returned function will always use v as the receiver. 970 | // It returns the zero Value if no method was found. 971 | func (v Value) MethodByName(name string) Value { 972 | return value_MethodByName(v, name) 973 | } 974 | 975 | // NumField returns the number of fields in the struct v. 976 | // It panics if v's Kind is not Struct. 977 | func (v Value) NumField() int { 978 | return value_NumField(v) 979 | } 980 | 981 | // NumMethod returns the number of exported methods in the value's method set. 982 | func (v Value) NumMethod() int { 983 | return value_NumMethod(v) 984 | } 985 | 986 | // OverflowComplex reports whether the complex128 x cannot be represented by v's type. 987 | // It panics if v's Kind is not Complex64 or Complex128. 988 | func (v Value) OverflowComplex(x complex128) bool { 989 | return value_OverflowComplex(v, x) 990 | } 991 | 992 | // OverflowFloat reports whether the float64 x cannot be represented by v's type. 993 | // It panics if v's Kind is not Float32 or Float64. 994 | func (v Value) OverflowFloat(x float64) bool { 995 | return value_OverflowFloat(v, x) 996 | } 997 | 998 | // OverflowInt reports whether the int64 x cannot be represented by v's type. 999 | // It panics if v's Kind is not Int, Int8, Int16, Int32, or Int64. 1000 | func (v Value) OverflowInt(x int64) bool { 1001 | return value_OverflowInt(v, x) 1002 | } 1003 | 1004 | // OverflowUint reports whether the uint64 x cannot be represented by v's type. 1005 | // It panics if v's Kind is not Uint, Uintptr, Uint8, Uint16, Uint32, or Uint64. 1006 | func (v Value) OverflowUint(x uint64) bool { 1007 | return value_OverflowUint(v, x) 1008 | } 1009 | 1010 | //go:nocheckptr 1011 | // This prevents inlining Value.Pointer when -d=checkptr is enabled, 1012 | // which ensures cmd/compile can recognize unsafe.Pointer(v.Pointer()) 1013 | // and make an exception. 1014 | 1015 | // Pointer returns v's value as a uintptr. 1016 | // It returns uintptr instead of unsafe.Pointer so that 1017 | // code using reflect cannot obtain unsafe.Pointers 1018 | // without importing the unsafe package explicitly. 1019 | // It panics if v's Kind is not Chan, Func, Map, Ptr, Slice, or UnsafePointer. 1020 | // 1021 | // If v's Kind is Func, the returned pointer is an underlying 1022 | // code pointer, but not necessarily enough to identify a 1023 | // single function uniquely. The only guarantee is that the 1024 | // result is zero if and only if v is a nil func Value. 1025 | // 1026 | // If v's Kind is Slice, the returned pointer is to the first 1027 | // element of the slice. If the slice is nil the returned value 1028 | // is 0. If the slice is empty but non-nil the return value is non-zero. 1029 | func (v Value) Pointer() uintptr { 1030 | return value_Pointer(v) 1031 | } 1032 | 1033 | // Recv receives and returns a value from the channel v. 1034 | // It panics if v's Kind is not Chan. 1035 | // The receive blocks until a value is ready. 1036 | // The boolean value ok is true if the value x corresponds to a send 1037 | // on the channel, false if it is a zero value received because the channel is closed. 1038 | func (v Value) Recv() (Value, bool) { 1039 | return value_Recv(v) 1040 | } 1041 | 1042 | // Send sends x on the channel v. 1043 | // It panics if v's kind is not Chan or if x's type is not the same type as v's element type. 1044 | // As in Go, x's value must be assignable to the channel's element type. 1045 | func (v Value) Send(x Value) { 1046 | value_Send(v, x) 1047 | } 1048 | 1049 | // Set assigns x to the value v. 1050 | // It panics if CanSet returns false. 1051 | // As in Go, x's value must be assignable to v's type. 1052 | func (v Value) Set(x Value) { 1053 | value_Set(v, x) 1054 | } 1055 | 1056 | // SetBool sets v's underlying value. 1057 | // It panics if v's Kind is not Bool or if CanSet() is false. 1058 | func (v Value) SetBool(x bool) { 1059 | value_SetBool(v, x) 1060 | } 1061 | 1062 | // SetBytes sets v's underlying value. 1063 | // It panics if v's underlying value is not a slice of bytes. 1064 | func (v Value) SetBytes(x []byte) { 1065 | value_SetBytes(v, x) 1066 | } 1067 | 1068 | // SetCap sets v's capacity to n. 1069 | // It panics if v's Kind is not Slice or if n is smaller than the length or 1070 | // greater than the capacity of the slice. 1071 | func (v Value) SetCap(n int) { 1072 | value_SetCap(v, n) 1073 | } 1074 | 1075 | // SetComplex sets v's underlying value to x. 1076 | // It panics if v's Kind is not Complex64 or Complex128, or if CanSet() is false. 1077 | func (v Value) SetComplex(x complex128) { 1078 | value_SetComplex(v, x) 1079 | } 1080 | 1081 | // SetFloat sets v's underlying value to x. 1082 | // It panics if v's Kind is not Float32 or Float64, or if CanSet() is false. 1083 | func (v Value) SetFloat(x float64) { 1084 | value_SetFloat(v, x) 1085 | } 1086 | 1087 | // SetInt sets v's underlying value to x. 1088 | // It panics if v's Kind is not Int, Int8, Int16, Int32, or Int64, or if CanSet() is false. 1089 | func (v Value) SetInt(x int64) { 1090 | value_SetInt(v, x) 1091 | } 1092 | 1093 | // SetLen sets v's length to n. 1094 | // It panics if v's Kind is not Slice or if n is negative or 1095 | // greater than the capacity of the slice. 1096 | func (v Value) SetLen(n int) { 1097 | value_SetLen(v, n) 1098 | } 1099 | 1100 | // SetMapIndex sets the element associated with key in the map v to elem. 1101 | // It panics if v's Kind is not Map. 1102 | // If elem is the zero Value, SetMapIndex deletes the key from the map. 1103 | // Otherwise if v holds a nil map, SetMapIndex will panic. 1104 | // As in Go, key's elem must be assignable to the map's key type, 1105 | // and elem's value must be assignable to the map's elem type. 1106 | func (v Value) SetMapIndex(key, elem Value) { 1107 | value_SetMapIndex(v, key, elem) 1108 | } 1109 | 1110 | // SetPointer sets the unsafe.Pointer value v to x. 1111 | // It panics if v's Kind is not UnsafePointer. 1112 | func (v Value) SetPointer(x unsafe.Pointer) { 1113 | value_SetPointer(v, x) 1114 | } 1115 | 1116 | // SetString sets v's underlying value to x. 1117 | // It panics if v's Kind is not String or if CanSet() is false. 1118 | func (v Value) SetString(x string) { 1119 | value_SetString(v, x) 1120 | } 1121 | 1122 | // SetUint sets v's underlying value to x. 1123 | // It panics if v's Kind is not Uint, Uintptr, Uint8, Uint16, Uint32, or Uint64, or if CanSet() is false. 1124 | func (v Value) SetUint(x uint64) { 1125 | value_SetUint(v, x) 1126 | } 1127 | 1128 | // Slice returns v[i:j]. 1129 | // It panics if v's Kind is not Array, Slice or String, or if v is an unaddressable array, 1130 | // or if the indexes are out of bounds. 1131 | func (v Value) Slice(i, j int) Value { 1132 | return value_Slice(v, i, j) 1133 | } 1134 | 1135 | // Slice3 is the 3-index form of the slice operation: it returns v[i:j:k]. 1136 | // It panics if v's Kind is not Array or Slice, or if v is an unaddressable array, 1137 | // or if the indexes are out of bounds. 1138 | func (v Value) Slice3(i, j, k int) Value { 1139 | return value_Slice3(v, i, j, k) 1140 | } 1141 | 1142 | // String returns the string v's underlying value, as a string. 1143 | // String is a special case because of Go's String method convention. 1144 | // Unlike the other getters, it does not panic if v's Kind is not String. 1145 | // Instead, it returns a string of the form "" where T is v's type. 1146 | // The fmt package treats Values specially. It does not call their String 1147 | // method implicitly but instead prints the concrete values they hold. 1148 | func (v Value) String() string { 1149 | return value_String(v) 1150 | } 1151 | 1152 | // TryRecv attempts to receive a value from the channel v but will not block. 1153 | // It panics if v's Kind is not Chan. 1154 | // If the receive delivers a value, x is the transferred value and ok is true. 1155 | // If the receive cannot finish without blocking, x is the zero Value and ok is false. 1156 | // If the channel is closed, x is the zero value for the channel's element type and ok is false. 1157 | func (v Value) TryRecv() (Value, bool) { 1158 | return value_TryRecv(v) 1159 | } 1160 | 1161 | // TrySend attempts to send x on the channel v but will not block. 1162 | // It panics if v's Kind is not Chan. 1163 | // It reports whether the value was sent. 1164 | // As in Go, x's value must be assignable to the channel's element type. 1165 | func (v Value) TrySend(x Value) bool { 1166 | return value_TrySend(v, x) 1167 | } 1168 | 1169 | // Type returns v's type. 1170 | func (v Value) Type() Type { 1171 | return value_Type(v) 1172 | } 1173 | 1174 | // Uint returns v's underlying value, as a uint64. 1175 | // It panics if v's Kind is not Uint, Uintptr, Uint8, Uint16, Uint32, or Uint64. 1176 | func (v Value) Uint() uint64 { 1177 | return value_Uint(v) 1178 | } 1179 | 1180 | //go:nocheckptr 1181 | // This prevents inlining Value.UnsafeAddr when -d=checkptr is enabled, 1182 | // which ensures cmd/compile can recognize unsafe.Pointer(v.UnsafeAddr()) 1183 | // and make an exception. 1184 | 1185 | // UnsafeAddr returns a pointer to v's data. 1186 | // It is for advanced clients that also import the "unsafe" package. 1187 | // It panics if v is not addressable. 1188 | func (v Value) UnsafeAddr() uintptr { 1189 | return value_UnsafeAddr(v) 1190 | } 1191 | -------------------------------------------------------------------------------- /reflect113.go: -------------------------------------------------------------------------------- 1 | // +build go1.13 2 | 3 | package reflect 4 | 5 | // IsZero reports whether v is the zero value for its type. 6 | // It panics if the argument is invalid. 7 | func (v Value) IsZero() bool { 8 | return toRV(v).IsZero() 9 | } 10 | -------------------------------------------------------------------------------- /reflect_test.go: -------------------------------------------------------------------------------- 1 | package reflect_test 2 | 3 | import ( 4 | "fmt" 5 | corereflect "reflect" 6 | "testing" 7 | "unsafe" 8 | 9 | "github.com/goccy/go-reflect" 10 | ) 11 | 12 | func TestTypeID(t *testing.T) { 13 | intID := reflect.TypeID(int(0)) 14 | if intID != reflect.TypeID(int(0)) { 15 | t.Fatal("failed to get typeid") 16 | } 17 | } 18 | 19 | func TestTypeAndPtrOf(t *testing.T) { 20 | typ, ptr := reflect.TypeAndPtrOf(int(10)) 21 | if typ.Kind() != reflect.Int { 22 | t.Fatal("failed to get type") 23 | } 24 | if *(*int)(ptr) != 10 { 25 | t.Fatal("failed to get ptr") 26 | } 27 | } 28 | 29 | func TestValueNoEscapeOf(t *testing.T) { 30 | v := reflect.ValueNoEscapeOf(&struct{ I int }{I: 10}) 31 | if v.Elem().Field(0).Int() != 10 { 32 | t.Fatal("failed to create reflect.Value from ValueNoEscapeOf") 33 | } 34 | } 35 | 36 | func TestToReflectType(t *testing.T) { 37 | typ := reflect.ToReflectType(reflect.TypeOf(1)) 38 | if fmt.Sprintf("%T", typ) != "*reflect.rtype" { 39 | t.Fatalf("failed to convert reflect.Type") 40 | } 41 | } 42 | 43 | func TestToReflectValue(t *testing.T) { 44 | v := reflect.ToReflectValue(reflect.ValueOf(1)) 45 | if fmt.Sprintf("%T", v) != "reflect.Value" { 46 | t.Fatalf("failed to convert reflect.Value") 47 | } 48 | } 49 | 50 | func TestToType(t *testing.T) { 51 | typ := reflect.ToType(corereflect.TypeOf(1)) 52 | if fmt.Sprintf("%T", typ) != "*reflect.rtype" { 53 | t.Fatalf("failed to convert reflect.Type") 54 | } 55 | } 56 | 57 | func TestToValue(t *testing.T) { 58 | v := reflect.ToValue(corereflect.ValueOf(1)) 59 | if fmt.Sprintf("%T", v) != "reflect.Value" { 60 | t.Fatalf("failed to convert reflect.Value") 61 | } 62 | } 63 | 64 | func TestNewAt(t *testing.T) { 65 | var i int 66 | 67 | ivalFromField := reflect.ValueOf(&struct{ foo int }{100}).Elem().Field(0) 68 | ival := reflect.ValueOf(&i).Elem() 69 | 70 | v := reflect.NewAt(ivalFromField.Type(), unsafe.Pointer(ivalFromField.UnsafeAddr())).Elem() 71 | ival.Set(v) 72 | v.Set(ival) 73 | if v.Int() != 100 { 74 | t.Fatal("failed to NewAt") 75 | } 76 | } 77 | 78 | func TestTypeBits(t *testing.T) { 79 | bits := reflect.TypeOf(1).Bits() 80 | if bits != 1<<6 { 81 | t.Fatal("failed to get bits from type") 82 | } 83 | } 84 | 85 | func TestTypeIsVariadic(t *testing.T) { 86 | if !reflect.TypeOf(func(...int) {}).IsVariadic() { 87 | t.Fatal("doesn't work IsVariadic") 88 | } 89 | } 90 | 91 | func TestTypeFieldByNameFunc(t *testing.T) { 92 | _, ok := reflect.TypeOf(struct { 93 | Foo int 94 | }{}).FieldByNameFunc(func(name string) bool { 95 | return name == "Foo" 96 | }) 97 | if !ok { 98 | t.Fatal("failed to FieldByNameFunc") 99 | } 100 | } 101 | 102 | func TestTypeLen(t *testing.T) { 103 | if reflect.TypeOf([3]int{}).Len() != 3 { 104 | t.Fatal("failed to Type.Len") 105 | } 106 | } 107 | 108 | func TestTypeOut(t *testing.T) { 109 | if reflect.TypeOf(func() int { return 0 }).Out(0).Kind() != reflect.Int { 110 | t.Fatal("failed to get output parameter") 111 | } 112 | } 113 | 114 | func TestTypeCanInterface(t *testing.T) { 115 | v := "hello" 116 | if !reflect.ValueOf(v).CanInterface() { 117 | t.Fatal("failed to Type.CanInterface") 118 | } 119 | } 120 | 121 | func TestValueFieldByNameFunc(t *testing.T) { 122 | field := reflect.ValueOf(struct { 123 | Foo int 124 | }{}).FieldByNameFunc(func(name string) bool { 125 | return name == "Foo" 126 | }) 127 | if field.Type().Kind() != reflect.Int { 128 | t.Fatal("failed to FieldByNameFunc") 129 | } 130 | } 131 | -------------------------------------------------------------------------------- /set_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2011 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 | "go/ast" 10 | "go/token" 11 | "io" 12 | "testing" 13 | "unsafe" 14 | 15 | . "github.com/goccy/go-reflect" 16 | ) 17 | 18 | func TestImplicitMapConversion(t *testing.T) { 19 | // Test implicit conversions in MapIndex and SetMapIndex. 20 | { 21 | // direct 22 | m := make(map[int]int) 23 | mv := ValueOf(m) 24 | mv.SetMapIndex(ValueOf(1), ValueOf(2)) 25 | x, ok := m[1] 26 | if x != 2 { 27 | t.Errorf("#1 after SetMapIndex(1,2): %d, %t (map=%v)", x, ok, m) 28 | } 29 | if n := mv.MapIndex(ValueOf(1)).Interface().(int); n != 2 { 30 | t.Errorf("#1 MapIndex(1) = %d", n) 31 | } 32 | } 33 | { 34 | // convert interface key 35 | m := make(map[interface{}]int) 36 | mv := ValueOf(m) 37 | mv.SetMapIndex(ValueOf(1), ValueOf(2)) 38 | x, ok := m[1] 39 | if x != 2 { 40 | t.Errorf("#2 after SetMapIndex(1,2): %d, %t (map=%v)", x, ok, m) 41 | } 42 | if n := mv.MapIndex(ValueOf(1)).Interface().(int); n != 2 { 43 | t.Errorf("#2 MapIndex(1) = %d", n) 44 | } 45 | } 46 | { 47 | // convert interface value 48 | m := make(map[int]interface{}) 49 | mv := ValueOf(m) 50 | mv.SetMapIndex(ValueOf(1), ValueOf(2)) 51 | x, ok := m[1] 52 | if x != 2 { 53 | t.Errorf("#3 after SetMapIndex(1,2): %d, %t (map=%v)", x, ok, m) 54 | } 55 | if n := mv.MapIndex(ValueOf(1)).Interface().(int); n != 2 { 56 | t.Errorf("#3 MapIndex(1) = %d", n) 57 | } 58 | } 59 | { 60 | // convert both interface key and interface value 61 | m := make(map[interface{}]interface{}) 62 | mv := ValueOf(m) 63 | mv.SetMapIndex(ValueOf(1), ValueOf(2)) 64 | x, ok := m[1] 65 | if x != 2 { 66 | t.Errorf("#4 after SetMapIndex(1,2): %d, %t (map=%v)", x, ok, m) 67 | } 68 | if n := mv.MapIndex(ValueOf(1)).Interface().(int); n != 2 { 69 | t.Errorf("#4 MapIndex(1) = %d", n) 70 | } 71 | } 72 | { 73 | // convert both, with non-empty interfaces 74 | m := make(map[io.Reader]io.Writer) 75 | mv := ValueOf(m) 76 | b1 := new(bytes.Buffer) 77 | b2 := new(bytes.Buffer) 78 | mv.SetMapIndex(ValueOf(b1), ValueOf(b2)) 79 | x, ok := m[b1] 80 | if x != b2 { 81 | t.Errorf("#5 after SetMapIndex(b1, b2): %p (!= %p), %t (map=%v)", x, b2, ok, m) 82 | } 83 | if p := mv.MapIndex(ValueOf(b1)).Elem().Pointer(); p != uintptr(unsafe.Pointer(b2)) { 84 | t.Errorf("#5 MapIndex(b1) = %#x want %p", p, b2) 85 | } 86 | } 87 | { 88 | // convert channel direction 89 | m := make(map[<-chan int]chan int) 90 | mv := ValueOf(m) 91 | c1 := make(chan int) 92 | c2 := make(chan int) 93 | mv.SetMapIndex(ValueOf(c1), ValueOf(c2)) 94 | x, ok := m[c1] 95 | if x != c2 { 96 | t.Errorf("#6 after SetMapIndex(c1, c2): %p (!= %p), %t (map=%v)", x, c2, ok, m) 97 | } 98 | if p := mv.MapIndex(ValueOf(c1)).Pointer(); p != ValueOf(c2).Pointer() { 99 | t.Errorf("#6 MapIndex(c1) = %#x want %p", p, c2) 100 | } 101 | } 102 | { 103 | // convert identical underlying types 104 | type MyBuffer bytes.Buffer 105 | m := make(map[*MyBuffer]*bytes.Buffer) 106 | mv := ValueOf(m) 107 | b1 := new(MyBuffer) 108 | b2 := new(bytes.Buffer) 109 | mv.SetMapIndex(ValueOf(b1), ValueOf(b2)) 110 | x, ok := m[b1] 111 | if x != b2 { 112 | t.Errorf("#7 after SetMapIndex(b1, b2): %p (!= %p), %t (map=%v)", x, b2, ok, m) 113 | } 114 | if p := mv.MapIndex(ValueOf(b1)).Pointer(); p != uintptr(unsafe.Pointer(b2)) { 115 | t.Errorf("#7 MapIndex(b1) = %#x want %p", p, b2) 116 | } 117 | } 118 | 119 | } 120 | 121 | func TestImplicitSetConversion(t *testing.T) { 122 | // Assume TestImplicitMapConversion covered the basics. 123 | // Just make sure conversions are being applied at all. 124 | var r io.Reader 125 | b := new(bytes.Buffer) 126 | rv := ValueOf(&r).Elem() 127 | rv.Set(ValueOf(b)) 128 | if r != b { 129 | t.Errorf("after Set: r=%T(%v)", r, r) 130 | } 131 | } 132 | 133 | func TestImplicitSendConversion(t *testing.T) { 134 | c := make(chan io.Reader, 10) 135 | b := new(bytes.Buffer) 136 | ValueOf(c).Send(ValueOf(b)) 137 | if bb := <-c; bb != b { 138 | t.Errorf("Received %p != %p", bb, b) 139 | } 140 | } 141 | 142 | func TestImplicitCallConversion(t *testing.T) { 143 | // Arguments must be assignable to parameter types. 144 | fv := ValueOf(io.WriteString) 145 | b := new(bytes.Buffer) 146 | fv.Call([]Value{ValueOf(b), ValueOf("hello world")}) 147 | if b.String() != "hello world" { 148 | t.Errorf("After call: string=%q want %q", b.String(), "hello world") 149 | } 150 | } 151 | 152 | func TestImplicitAppendConversion(t *testing.T) { 153 | // Arguments must be assignable to the slice's element type. 154 | s := []io.Reader{} 155 | sv := ValueOf(&s).Elem() 156 | b := new(bytes.Buffer) 157 | sv.Set(Append(sv, ValueOf(b))) 158 | if len(s) != 1 || s[0] != b { 159 | t.Errorf("after append: s=%v want [%p]", s, b) 160 | } 161 | } 162 | 163 | var implementsTests = []struct { 164 | x interface{} 165 | t interface{} 166 | b bool 167 | }{ 168 | {new(*bytes.Buffer), new(io.Reader), true}, 169 | {new(bytes.Buffer), new(io.Reader), false}, 170 | {new(*bytes.Buffer), new(io.ReaderAt), false}, 171 | {new(*ast.Ident), new(ast.Expr), true}, 172 | {new(*notAnExpr), new(ast.Expr), false}, 173 | {new(*ast.Ident), new(notASTExpr), false}, 174 | {new(notASTExpr), new(ast.Expr), false}, 175 | {new(ast.Expr), new(notASTExpr), false}, 176 | {new(*notAnExpr), new(notASTExpr), true}, 177 | } 178 | 179 | type notAnExpr struct{} 180 | 181 | func (notAnExpr) Pos() token.Pos { return token.NoPos } 182 | func (notAnExpr) End() token.Pos { return token.NoPos } 183 | func (notAnExpr) exprNode() {} 184 | 185 | type notASTExpr interface { 186 | Pos() token.Pos 187 | End() token.Pos 188 | exprNode() 189 | } 190 | 191 | func TestImplements(t *testing.T) { 192 | for _, tt := range implementsTests { 193 | xv := TypeOf(tt.x).Elem() 194 | xt := TypeOf(tt.t).Elem() 195 | if b := xv.Implements(xt); b != tt.b { 196 | t.Errorf("(%s).Implements(%s) = %v, want %v", xv.String(), xt.String(), b, tt.b) 197 | } 198 | } 199 | } 200 | 201 | var assignableTests = []struct { 202 | x interface{} 203 | t interface{} 204 | b bool 205 | }{ 206 | {new(chan int), new(<-chan int), true}, 207 | {new(<-chan int), new(chan int), false}, 208 | {new(*int), new(IntPtr), true}, 209 | {new(IntPtr), new(*int), true}, 210 | {new(IntPtr), new(IntPtr1), false}, 211 | {new(Ch), new(<-chan interface{}), true}, 212 | // test runs implementsTests too 213 | } 214 | 215 | type IntPtr *int 216 | type IntPtr1 *int 217 | type Ch <-chan interface{} 218 | 219 | func TestAssignableTo(t *testing.T) { 220 | for _, tt := range append(assignableTests, implementsTests...) { 221 | xv := TypeOf(tt.x).Elem() 222 | xt := TypeOf(tt.t).Elem() 223 | if b := xv.AssignableTo(xt); b != tt.b { 224 | t.Errorf("(%s).AssignableTo(%s) = %v, want %v", xv.String(), xt.String(), b, tt.b) 225 | } 226 | } 227 | } 228 | -------------------------------------------------------------------------------- /tostring_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2009 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 | // Formatting of reflection types and values for debugging. 6 | // Not defined as methods so they do not need to be linked into most binaries; 7 | // the functions are not used by the library itself, only in tests. 8 | 9 | package reflect_test 10 | 11 | import ( 12 | "strconv" 13 | 14 | . "github.com/goccy/go-reflect" 15 | ) 16 | 17 | // valueToString returns a textual representation of the reflection value val. 18 | // For debugging only. 19 | func valueToString(val Value) string { 20 | var str string 21 | if !val.IsValid() { 22 | return "" 23 | } 24 | typ := val.Type() 25 | switch val.Kind() { 26 | case Int, Int8, Int16, Int32, Int64: 27 | return strconv.FormatInt(val.Int(), 10) 28 | case Uint, Uint8, Uint16, Uint32, Uint64, Uintptr: 29 | return strconv.FormatUint(val.Uint(), 10) 30 | case Float32, Float64: 31 | return strconv.FormatFloat(val.Float(), 'g', -1, 64) 32 | case Complex64, Complex128: 33 | c := val.Complex() 34 | return strconv.FormatFloat(real(c), 'g', -1, 64) + "+" + strconv.FormatFloat(imag(c), 'g', -1, 64) + "i" 35 | case String: 36 | return val.String() 37 | case Bool: 38 | if val.Bool() { 39 | return "true" 40 | } else { 41 | return "false" 42 | } 43 | case Ptr: 44 | v := val 45 | str = typ.String() + "(" 46 | if v.IsNil() { 47 | str += "0" 48 | } else { 49 | str += "&" + valueToString(v.Elem()) 50 | } 51 | str += ")" 52 | return str 53 | case Array, Slice: 54 | v := val 55 | str += typ.String() 56 | str += "{" 57 | for i := 0; i < v.Len(); i++ { 58 | if i > 0 { 59 | str += ", " 60 | } 61 | str += valueToString(v.Index(i)) 62 | } 63 | str += "}" 64 | return str 65 | case Map: 66 | t := typ 67 | str = t.String() 68 | str += "{" 69 | str += "" 70 | str += "}" 71 | return str 72 | case Chan: 73 | str = typ.String() 74 | return str 75 | case Struct: 76 | t := typ 77 | v := val 78 | str += t.String() 79 | str += "{" 80 | for i, n := 0, v.NumField(); i < n; i++ { 81 | if i > 0 { 82 | str += ", " 83 | } 84 | str += valueToString(v.Field(i)) 85 | } 86 | str += "}" 87 | return str 88 | case Interface: 89 | return typ.String() + "(" + valueToString(val.Elem()) + ")" 90 | case Func: 91 | v := val 92 | return typ.String() + "(" + strconv.FormatUint(uint64(v.Pointer()), 10) + ")" 93 | default: 94 | panic("valueToString: can't print type " + typ.String()) 95 | } 96 | } 97 | -------------------------------------------------------------------------------- /type.go: -------------------------------------------------------------------------------- 1 | package reflect 2 | 3 | import ( 4 | "reflect" 5 | _ "unsafe" 6 | ) 7 | 8 | //go:linkname ifaceIndir reflect.ifaceIndir 9 | //go:noescape 10 | func ifaceIndir(Type) bool 11 | 12 | func arrayOf(i int, typ Type) Type { 13 | return toT(reflect.ArrayOf(i, toRT(typ))) 14 | } 15 | 16 | func chanOf(dir ChanDir, typ Type) Type { 17 | return toT(reflect.ChanOf(dir, toRT(typ))) 18 | } 19 | 20 | func funcOf(in []Type, out []Type, variadic bool) Type { 21 | return toT(reflect.FuncOf(toRTs(in), toRTs(out), variadic)) 22 | } 23 | 24 | func mapOf(key Type, elem Type) Type { 25 | return toT(reflect.MapOf(toRT(key), toRT(elem))) 26 | } 27 | 28 | func ptrTo(typ Type) Type { 29 | return toT(reflect.PtrTo(toRT(typ))) 30 | } 31 | 32 | func sliceOf(t Type) Type { 33 | return toT(reflect.SliceOf(toRT(t))) 34 | } 35 | 36 | func structOf(fields []StructField) Type { 37 | return ToType(reflect.StructOf(toRSFs(fields))) 38 | } 39 | 40 | //go:linkname type_Align reflect.(*rtype).Align 41 | //go:noescape 42 | func type_Align(Type) int 43 | 44 | //go:linkname type_FieldAlign reflect.(*rtype).FieldAlign 45 | //go:noescape 46 | func type_FieldAlign(Type) int 47 | 48 | //go:linkname type_Method reflect.(*rtype).Method 49 | //go:noescape 50 | func type_Method(Type, int) reflect.Method 51 | 52 | //go:linkname type_MethodByName reflect.(*rtype).MethodByName 53 | //go:noescape 54 | func type_MethodByName(Type, string) (reflect.Method, bool) 55 | 56 | //go:linkname type_NumMethod reflect.(*rtype).NumMethod 57 | //go:noescape 58 | func type_NumMethod(Type) int 59 | 60 | //go:linkname type_Name reflect.(*rtype).Name 61 | //go:noescape 62 | func type_Name(Type) string 63 | 64 | //go:linkname type_PkgPath reflect.(*rtype).PkgPath 65 | //go:noescape 66 | func type_PkgPath(Type) string 67 | 68 | //go:linkname type_Size reflect.(*rtype).Size 69 | //go:noescape 70 | func type_Size(Type) uintptr 71 | 72 | //go:linkname type_String reflect.(*rtype).String 73 | //go:noescape 74 | func type_String(Type) string 75 | 76 | //go:linkname type_Kind reflect.(*rtype).Kind 77 | //go:noescape 78 | func type_Kind(Type) reflect.Kind 79 | 80 | //go:linkname type_Implements reflect.(*rtype).Implements 81 | //go:noescape 82 | func type_Implements(Type, reflect.Type) bool 83 | 84 | //go:linkname type_AssignableTo reflect.(*rtype).AssignableTo 85 | //go:noescape 86 | func type_AssignableTo(Type, reflect.Type) bool 87 | 88 | //go:linkname type_ConvertibleTo reflect.(*rtype).ConvertibleTo 89 | //go:noescape 90 | func type_ConvertibleTo(Type, reflect.Type) bool 91 | 92 | //go:linkname type_Comparable reflect.(*rtype).Comparable 93 | //go:noescape 94 | func type_Comparable(Type) bool 95 | 96 | //go:linkname type_Bits reflect.(*rtype).Bits 97 | //go:noescape 98 | func type_Bits(Type) int 99 | 100 | //go:linkname type_ChanDir reflect.(*rtype).ChanDir 101 | //go:noescape 102 | func type_ChanDir(Type) ChanDir 103 | 104 | //go:linkname type_IsVariadic reflect.(*rtype).IsVariadic 105 | //go:noescape 106 | func type_IsVariadic(Type) bool 107 | 108 | //go:linkname type_Elem reflect.(*rtype).Elem 109 | //go:noescape 110 | func type_Elem(t Type) reflect.Type 111 | 112 | //go:linkname type_Field reflect.(*rtype).Field 113 | //go:noescape 114 | func type_Field(typ Type, i int) reflect.StructField 115 | 116 | //go:linkname type_FieldByIndex reflect.(*rtype).FieldByIndex 117 | //go:noescape 118 | func type_FieldByIndex(Type, []int) reflect.StructField 119 | 120 | //go:linkname type_FieldByName reflect.(*rtype).FieldByName 121 | //go:noescape 122 | func type_FieldByName(Type, string) (reflect.StructField, bool) 123 | 124 | //go:linkname type_FieldByNameFunc reflect.(*rtype).FieldByNameFunc 125 | //go:noescape 126 | func type_FieldByNameFunc(Type, func(string) bool) (reflect.StructField, bool) 127 | 128 | //go:linkname type_In reflect.(*rtype).In 129 | //go:noescape 130 | func type_In(Type, int) reflect.Type 131 | 132 | //go:linkname type_Key reflect.(*rtype).Key 133 | //go:noescape 134 | func type_Key(Type) reflect.Type 135 | 136 | //go:linkname type_Len reflect.(*rtype).Len 137 | //go:noescape 138 | func type_Len(Type) int 139 | 140 | //go:linkname type_NumField reflect.(*rtype).NumField 141 | //go:noescape 142 | func type_NumField(Type) int 143 | 144 | //go:linkname type_NumIn reflect.(*rtype).NumIn 145 | //go:noescape 146 | func type_NumIn(Type) int 147 | 148 | //go:linkname type_NumOut reflect.(*rtype).NumOut 149 | //go:noescape 150 | func type_NumOut(Type) int 151 | 152 | //go:linkname type_Out reflect.(*rtype).Out 153 | //go:noescape 154 | func type_Out(Type, int) reflect.Type 155 | 156 | //go:linkname type_toType reflect.toType 157 | //go:noescape 158 | func type_toType(t Type) reflect.Type 159 | 160 | var dummy struct { 161 | b bool 162 | x interface{} 163 | } 164 | 165 | func escape(x interface{}) { 166 | if dummy.b { 167 | dummy.x = x 168 | } 169 | } 170 | -------------------------------------------------------------------------------- /value.go: -------------------------------------------------------------------------------- 1 | package reflect 2 | 3 | import ( 4 | "reflect" 5 | "unsafe" 6 | ) 7 | 8 | func value_Copy(dst Value, src Value) int { 9 | return reflect.Copy(toRV(dst), toRV(src)) 10 | } 11 | 12 | func value_Append(v Value, args ...Value) Value { 13 | return toV(reflect.Append(toRV(v), toRVs(args)...)) 14 | } 15 | 16 | func value_AppendSlice(s, t Value) Value { 17 | return toV(reflect.AppendSlice(toRV(s), toRV(t))) 18 | } 19 | 20 | func value_Indirect(v Value) Value { 21 | return toV(reflect.Indirect(toRV(v))) 22 | } 23 | 24 | func value_MakeChan(typ Type, buffer int) Value { 25 | return toV(reflect.MakeChan(toRT(typ), buffer)) 26 | } 27 | 28 | func value_MakeFunc(typ Type, fn func([]Value) []Value) Value { 29 | return toV(reflect.MakeFunc(toRT(typ), func(args []reflect.Value) []reflect.Value { 30 | return toRVs(fn(toVs(args))) 31 | })) 32 | } 33 | 34 | func value_MakeMap(typ Type) Value { 35 | return toV(reflect.MakeMap(toRT(typ))) 36 | } 37 | 38 | func value_MakeMapWithSize(typ Type, n int) Value { 39 | return toV(reflect.MakeMapWithSize(toRT(typ), n)) 40 | } 41 | 42 | func value_MakeSlice(typ Type, len, cap int) Value { 43 | return toV(reflect.MakeSlice(toRT(typ), len, cap)) 44 | } 45 | 46 | func value_New(typ Type) Value { 47 | return toV(reflect.New(toRT(typ))) 48 | } 49 | 50 | func value_NewAt(typ Type, p unsafe.Pointer) Value { 51 | return toV(reflect.NewAt(toRT(typ), p)) 52 | } 53 | 54 | func value_Select(cases []SelectCase) (int, Value, bool) { 55 | chosen, recv, recvOK := reflect.Select(toRSCs(cases)) 56 | return chosen, toV(recv), recvOK 57 | } 58 | 59 | func value_Zero(typ Type) Value { 60 | return toV(reflect.Zero(toRT(typ))) 61 | } 62 | 63 | func value_Addr(v Value) Value { 64 | return toV(toRV(v).Addr()) 65 | } 66 | 67 | func value_Bool(v Value) bool { 68 | return toRV(v).Bool() 69 | } 70 | 71 | func value_Bytes(v Value) []byte { 72 | return toRV(v).Bytes() 73 | } 74 | 75 | func value_Call(v Value, in []Value) []Value { 76 | return toVs(toRV(v).Call(toRVs(in))) 77 | } 78 | 79 | func value_CallSlice(v Value, in []Value) []Value { 80 | return toVs(toRV(v).CallSlice(toRVs(in))) 81 | } 82 | 83 | func value_CanAddr(v Value) bool { 84 | return toRV(v).CanAddr() 85 | } 86 | 87 | func value_CanSet(v Value) bool { 88 | return toRV(v).CanSet() 89 | } 90 | 91 | func value_CanInterface(v Value) bool { 92 | return toRV(v).CanInterface() 93 | } 94 | 95 | func value_Cap(v Value) int { 96 | return toRV(v).Cap() 97 | } 98 | 99 | func value_Close(v Value) { 100 | toRV(v).Close() 101 | } 102 | 103 | func value_Complex(v Value) complex128 { 104 | return toRV(v).Complex() 105 | } 106 | 107 | func value_Convert(v Value, typ Type) Value { 108 | return toV(toRV(v).Convert(toRT(typ))) 109 | } 110 | 111 | func value_Elem(v Value) Value { 112 | return toV(toRV(v).Elem()) 113 | } 114 | 115 | func value_Field(v Value, i int) Value { 116 | return toV(toRV(v).Field(i)) 117 | } 118 | 119 | func value_FieldByIndex(v Value, i []int) Value { 120 | return toV(toRV(v).FieldByIndex(i)) 121 | } 122 | 123 | func value_FieldByName(v Value, name string) Value { 124 | return toV(toRV(v).FieldByName(name)) 125 | } 126 | 127 | func value_FieldByNameFunc(v Value, fn func(string) bool) Value { 128 | return toV(toRV(v).FieldByNameFunc(fn)) 129 | } 130 | 131 | func value_Float(v Value) float64 { 132 | return toRV(v).Float() 133 | } 134 | 135 | func value_Index(v Value, i int) Value { 136 | return toV(toRV(v).Index(i)) 137 | } 138 | 139 | func value_Int(v Value) int64 { 140 | return toRV(v).Int() 141 | } 142 | 143 | func value_Interface(v Value) interface{} { 144 | return toRV(v).Interface() 145 | } 146 | 147 | func value_InterfaceData(v Value) [2]uintptr { 148 | return toRV(v).InterfaceData() 149 | } 150 | 151 | func value_IsNil(v Value) bool { 152 | return toRV(v).IsNil() 153 | } 154 | 155 | func value_IsValid(v Value) bool { 156 | return toRV(v).IsValid() 157 | } 158 | 159 | func value_Kind(v Value) Kind { 160 | return toRV(v).Kind() 161 | } 162 | 163 | func value_Len(v Value) int { 164 | return toRV(v).Len() 165 | } 166 | 167 | func value_MapIndex(v Value, key Value) Value { 168 | return toV(toRV(v).MapIndex(toRV(key))) 169 | } 170 | 171 | func value_MapKeys(v Value) []Value { 172 | return toVs(toRV(v).MapKeys()) 173 | } 174 | 175 | func value_MapRange(v Value) *MapIter { 176 | return (*MapIter)(toRV(v).MapRange()) 177 | } 178 | 179 | func value_Method(v Value, i int) Value { 180 | return toV(toRV(v).Method(i)) 181 | } 182 | 183 | func value_MethodByName(v Value, name string) Value { 184 | return toV(toRV(v).MethodByName(name)) 185 | } 186 | 187 | func value_NumField(v Value) int { 188 | return toRV(v).NumField() 189 | } 190 | 191 | func value_NumMethod(v Value) int { 192 | return toRV(v).NumMethod() 193 | } 194 | 195 | func value_OverflowComplex(v Value, c complex128) bool { 196 | return toRV(v).OverflowComplex(c) 197 | } 198 | 199 | func value_OverflowFloat(v Value, f float64) bool { 200 | return toRV(v).OverflowFloat(f) 201 | } 202 | 203 | func value_OverflowInt(v Value, i int64) bool { 204 | return toRV(v).OverflowInt(i) 205 | } 206 | 207 | func value_OverflowUint(v Value, u uint64) bool { 208 | return toRV(v).OverflowUint(u) 209 | } 210 | 211 | func value_Pointer(v Value) uintptr { 212 | return toRV(v).Pointer() 213 | } 214 | 215 | func value_Recv(v Value) (Value, bool) { 216 | value, ok := toRV(v).Recv() 217 | return toV(value), ok 218 | } 219 | 220 | func value_Send(v Value, x Value) { 221 | toRV(v).Send(toRV(x)) 222 | } 223 | 224 | func value_Set(v Value, x Value) { 225 | toRV(v).Set(toRV(x)) 226 | } 227 | 228 | func value_SetBool(v Value, b bool) { 229 | toRV(v).SetBool(b) 230 | } 231 | 232 | func value_SetBytes(v Value, b []byte) { 233 | toRV(v).SetBytes(b) 234 | } 235 | 236 | func value_SetCap(v Value, i int) { 237 | toRV(v).SetCap(i) 238 | } 239 | 240 | func value_SetComplex(v Value, c complex128) { 241 | toRV(v).SetComplex(c) 242 | } 243 | 244 | func value_SetFloat(v Value, f float64) { 245 | toRV(v).SetFloat(f) 246 | } 247 | 248 | func value_SetInt(v Value, i int64) { 249 | toRV(v).SetInt(i) 250 | } 251 | 252 | func value_SetLen(v Value, i int) { 253 | toRV(v).SetLen(i) 254 | } 255 | 256 | func value_SetMapIndex(v Value, key Value, elem Value) { 257 | toRV(v).SetMapIndex(toRV(key), toRV(elem)) 258 | } 259 | 260 | func value_SetPointer(v Value, p unsafe.Pointer) { 261 | toRV(v).SetPointer(p) 262 | } 263 | 264 | func value_SetString(v Value, s string) { 265 | toRV(v).SetString(s) 266 | } 267 | 268 | func value_SetUint(v Value, u uint64) { 269 | toRV(v).SetUint(u) 270 | } 271 | 272 | func value_Slice(v Value, i int, j int) Value { 273 | return toV(toRV(v).Slice(i, j)) 274 | } 275 | 276 | func value_Slice3(v Value, i int, j int, k int) Value { 277 | return toV(toRV(v).Slice3(i, j, k)) 278 | } 279 | 280 | func value_String(v Value) string { 281 | return toRV(v).String() 282 | } 283 | 284 | func value_TryRecv(v Value) (Value, bool) { 285 | value, ok := toRV(v).TryRecv() 286 | return toV(value), ok 287 | } 288 | 289 | func value_TrySend(v Value, x Value) bool { 290 | return toRV(v).TrySend(toRV(x)) 291 | } 292 | 293 | func value_Type(v Value) Type { 294 | return ToType(toRV(v).Type()) 295 | } 296 | 297 | func value_Uint(v Value) uint64 { 298 | return toRV(v).Uint() 299 | } 300 | 301 | func value_UnsafeAddr(v Value) uintptr { 302 | return toRV(v).UnsafeAddr() 303 | } 304 | --------------------------------------------------------------------------------