// Copyright 2009 The Go Authors. All rights reserved.// Use of this source code is governed by a BSD-style// license that can be found in the LICENSE file.package reflectimport ()constptrSize = 4 << (^uintptr(0) >> 63) // unsafe.Sizeof(uintptr(0)) but an ideal const// Value is the reflection interface to a Go value.//// Not all methods apply to all kinds of values. Restrictions,// if any, are noted in the documentation for each method.// Use the Kind method to find out the kind of value before// calling kind-specific methods. Calling a method// inappropriate to the kind of type causes a run time panic.//// The zero Value represents no value.// Its IsValid method returns false, its Kind method returns Invalid,// its String method returns "<invalid Value>", and all other methods panic.// Most functions and methods never return an invalid value.// If one does, its documentation states the conditions explicitly.//// A Value can be used concurrently by multiple goroutines provided that// the underlying Go value can be used concurrently for the equivalent// direct operations.//// To compare two Values, compare the results of the Interface method.// Using == on two Values does not compare the underlying values// they represent.typeValuestruct {// typ holds the type of the value represented by a Value. typ *rtype// Pointer-valued data or, if flagIndir is set, pointer to data. // Valid when either flagIndir is set or typ.pointers() is true. ptr unsafe.Pointer// flag holds metadata about the value. // The lowest bits are flag bits: // - flagStickyRO: obtained via unexported not embedded field, so read-only // - flagEmbedRO: obtained via unexported embedded field, so read-only // - flagIndir: val holds a pointer to the data // - flagAddr: v.CanAddr is true (implies flagIndir) // - flagMethod: v is a method value. // The next five bits give the Kind of the value. // This repeats typ.Kind() except for method values. // The remaining 23+ bits give a method number for method values. // If flag.kind() != Func, code can assume that flagMethod is unset. // If ifaceIndir(typ), code can assume that flagIndir is set.flag// A method value represents a curried method invocation // like r.Read for some receiver r. The typ+val+flag bits describe // the receiver r, but the flag's Kind bits say Func (methods are // functions), and the top bits of the flag give the method number // in r's type's method table.}typeflaguintptrconst (flagKindWidth = 5// there are 27 kindsflagKindMaskflag = 1<<flagKindWidth - 1flagStickyROflag = 1 << 5flagEmbedROflag = 1 << 6flagIndirflag = 1 << 7flagAddrflag = 1 << 8flagMethodflag = 1 << 9flagMethodShift = 10flagROflag = flagStickyRO | flagEmbedRO)func ( flag) () Kind {returnKind( & flagKindMask)}func ( flag) () flag {if &flagRO != 0 {returnflagStickyRO }return0}// pointer returns the underlying pointer represented by v.// v.Kind() must be Ptr, Map, Chan, Func, or UnsafePointer// if v.Kind() == Ptr, the base type must not be go:notinheap.func ( Value) () unsafe.Pointer {if .typ.size != ptrSize || !.typ.pointers() {panic("can't call pointer on a non-pointer Value") }if .flag&flagIndir != 0 {return *(*unsafe.Pointer)(.ptr) }return .ptr}// packEface converts v to the empty interface.func ( Value) interface{} { := .typvarinterface{} := (*emptyInterface)(unsafe.Pointer(&))// First, fill in the data portion of the interface.switch {caseifaceIndir():if .flag&flagIndir == 0 {panic("bad indir") }// Value is indirect, and so is the interface we're making. := .ptrif .flag&flagAddr != 0 {// TODO: pass safe boolean from valueInterface so // we don't need to copy if safe==true? := unsafe_New()typedmemmove(, , ) = } .word = case .flag&flagIndir != 0:// Value is indirect, but interface is direct. We need // to load the data at v.ptr into the interface data word. .word = *(*unsafe.Pointer)(.ptr)default:// Value is direct, and so is the interface. .word = .ptr }// Now, fill in the type portion. We're very careful here not // to have any operation between the e.word and e.typ assignments // that would let the garbage collector observe the partially-built // interface value. .typ = return}// unpackEface converts the empty interface i to a Value.func ( interface{}) Value { := (*emptyInterface)(unsafe.Pointer(&))// NOTE: don't read e.word until we know whether it is really a pointer or not. := .typif == nil {returnValue{} } := flag(.Kind())ififaceIndir() { |= flagIndir }returnValue{, .word, }}// A ValueError occurs when a Value method is invoked on// a Value that does not support it. Such cases are documented// in the description of each method.typeValueErrorstruct { Method string Kind Kind}func ( *ValueError) () string {if .Kind == 0 {return"reflect: call of " + .Method + " on zero Value" }return"reflect: call of " + .Method + " on " + .Kind.String() + " Value"}// methodName returns the name of the calling method,// assumed to be two stack frames above.func () string { , , , := runtime.Caller(2) := runtime.FuncForPC()if == nil {return"unknown method" }return .Name()}// methodNameSkip is like methodName, but skips another stack frame.// This is a separate function so that reflect.flag.mustBe will be inlined.func () string { , , , := runtime.Caller(3) := runtime.FuncForPC()if == nil {return"unknown method" }return .Name()}// emptyInterface is the header for an interface{} value.typeemptyInterfacestruct { typ *rtype word unsafe.Pointer}// nonEmptyInterface is the header for an interface value with methods.typenonEmptyInterfacestruct {// see ../runtime/iface.go:/Itab itab *struct { ityp *rtype// static interface type typ *rtype// dynamic concrete type hash uint32// copy of typ.hash _ [4]byte fun [100000]unsafe.Pointer// method table } word unsafe.Pointer}// mustBe panics if f's kind is not expected.// Making this a method on flag instead of on Value// (and embedding flag in Value) means that we can write// the very clear v.mustBe(Bool) and have it compile into// v.flag.mustBe(Bool), which will only bother to copy the// single important word for the receiver.func ( flag) ( Kind) {// TODO(mvdan): use f.kind() again once mid-stack inlining gets betterifKind(&flagKindMask) != {panic(&ValueError{methodName(), .kind()}) }}// mustBeExported panics if f records that the value was obtained using// an unexported field.func ( flag) () {if == 0 || &flagRO != 0 { .mustBeExportedSlow() }}func ( flag) () {if == 0 {panic(&ValueError{methodNameSkip(), Invalid}) }if &flagRO != 0 {panic("reflect: " + methodNameSkip() + " using value obtained using unexported field") }}// mustBeAssignable panics if f records that the value is not assignable,// which is to say that either it was obtained using an unexported field// or it is not addressable.func ( flag) () {if &flagRO != 0 || &flagAddr == 0 { .mustBeAssignableSlow() }}func ( flag) () {if == 0 {panic(&ValueError{methodNameSkip(), Invalid}) }// Assignable if addressable and not read-only.if &flagRO != 0 {panic("reflect: " + methodNameSkip() + " using value obtained using unexported field") }if &flagAddr == 0 {panic("reflect: " + methodNameSkip() + " using unaddressable value") }}// Addr returns a pointer value representing the address of v.// It panics if CanAddr() returns false.// Addr is typically used to obtain a pointer to a struct field// or slice element in order to call a method that requires a// pointer receiver.func ( Value) () Value {if .flag&flagAddr == 0 {panic("reflect.Value.Addr of unaddressable value") }// Preserve flagRO instead of using v.flag.ro() so that // v.Addr().Elem() is equivalent to v (#32772) := .flag & flagROreturnValue{.typ.ptrTo(), .ptr, | flag(Ptr)}}// Bool returns v's underlying value.// It panics if v's kind is not Bool.func ( Value) () bool { .mustBe(Bool)return *(*bool)(.ptr)}// Bytes returns v's underlying value.// It panics if v's underlying value is not a slice of bytes.func ( Value) () []byte { .mustBe(Slice)if .typ.Elem().Kind() != Uint8 {panic("reflect.Value.Bytes of non-byte slice") }// Slice is always bigger than a word; assume flagIndir.return *(*[]byte)(.ptr)}// runes returns v's underlying value.// It panics if v's underlying value is not a slice of runes (int32s).func ( Value) () []rune { .mustBe(Slice)if .typ.Elem().Kind() != Int32 {panic("reflect.Value.Bytes of non-rune slice") }// Slice is always bigger than a word; assume flagIndir.return *(*[]rune)(.ptr)}// CanAddr reports whether the value's address can be obtained with Addr.// Such values are called addressable. A value is addressable if it is// an element of a slice, an element of an addressable array,// a field of an addressable struct, or the result of dereferencing a pointer.// If CanAddr returns false, calling Addr will panic.func ( Value) () bool {return .flag&flagAddr != 0}// CanSet reports whether the value of v can be changed.// A Value can be changed only if it is addressable and was not// obtained by the use of unexported struct fields.// If CanSet returns false, calling Set or any type-specific// setter (e.g., SetBool, SetInt) will panic.func ( Value) () bool {return .flag&(flagAddr|flagRO) == flagAddr}// Call calls the function v with the input arguments in.// For example, if len(in) == 3, v.Call(in) represents the Go call v(in[0], in[1], in[2]).// Call panics if v's Kind is not Func.// It returns the output results as Values.// As in Go, each input argument must be assignable to the// type of the function's corresponding input parameter.// If v is a variadic function, Call creates the variadic slice parameter// itself, copying in the corresponding values.func ( Value) ( []Value) []Value { .mustBe(Func) .mustBeExported()return .call("Call", )}// CallSlice calls the variadic function v with the input arguments in,// assigning the slice in[len(in)-1] to v's final variadic argument.// For example, if len(in) == 3, v.CallSlice(in) represents the Go call v(in[0], in[1], in[2]...).// CallSlice panics if v's Kind is not Func or if v is not variadic.// It returns the output results as Values.// As in Go, each input argument must be assignable to the// type of the function's corresponding input parameter.func ( Value) ( []Value) []Value { .mustBe(Func) .mustBeExported()return .call("CallSlice", )}varcallGCbool// for testing; see TestCallMethodJumpfunc ( Value) ( string, []Value) []Value {// Get function pointer, type. := (*funcType)(unsafe.Pointer(.typ))var (unsafe.PointerValue *rtype )if .flag&flagMethod != 0 { = , , = methodReceiver(, , int(.flag)>>flagMethodShift) } elseif .flag&flagIndir != 0 { = *(*unsafe.Pointer)(.ptr) } else { = .ptr }if == nil {panic("reflect.Value.Call: call of nil function") } := == "CallSlice" := .NumIn()if {if !.IsVariadic() {panic("reflect: CallSlice of non-variadic function") }iflen() < {panic("reflect: CallSlice with too few input arguments") }iflen() > {panic("reflect: CallSlice with too many input arguments") } } else {if .IsVariadic() { -- }iflen() < {panic("reflect: Call with too few input arguments") }if !.IsVariadic() && len() > {panic("reflect: Call with too many input arguments") } }for , := range {if .Kind() == Invalid {panic("reflect: " + + " using zero Value argument") } }for := 0; < ; ++ {if , := [].Type(), .In(); !.AssignableTo() {panic("reflect: " + + " using " + .String() + " as type " + .String()) } }if ! && .IsVariadic() {// prepare slice for remaining values := len() - := MakeSlice(.In(), , ) := .In().Elem()for := 0; < ; ++ { := [+]if := .Type(); !.AssignableTo() {panic("reflect: cannot use " + .String() + " as type " + .String() + " in " + ) } .Index().Set() } := = make([]Value, +1)copy([:], ) [] = } := len()if != .NumIn() {panic("reflect.Value.Call: wrong argument count") } := .NumOut()// Compute frame type. , , , , := funcLayout(, )// Allocate a chunk of memory for frame.varunsafe.Pointerif == 0 { = .Get().(unsafe.Pointer) } else {// Can't use pool if the function has return values. // We will leak pointer to args in ret, so its lifetime is not scoped. = unsafe_New() } := uintptr(0)// Copy inputs into args.if != nil {storeRcvr(, ) = ptrSize }for , := range { .mustBeExported() := .In().(*rtype) := uintptr(.align) = ( + - 1) &^ ( - 1) := .sizeif == 0 {// Not safe to compute args+off pointing at 0 bytes, // because that might point beyond the end of the frame, // but we still need to call assignTo to check assignability. .assignTo("reflect.Value.Call", , nil)continue } := add(, , "n > 0") = .assignTo("reflect.Value.Call", , )if .flag&flagIndir != 0 {typedmemmove(, , .ptr) } else { *(*unsafe.Pointer)() = .ptr } += }// Call.call(, , , uint32(.size), uint32())// For testing; see TestCallMethodJump.ifcallGC {runtime.GC() }var []Valueif == 0 {typedmemclr(, ) .Put() } else {// Zero the now unused input area of args, // because the Values returned by this function contain pointers to the args object, // and will thus keep the args object alive indefinitely.typedmemclrpartial(, , 0, )// Wrap Values around return values in args. = make([]Value, ) = for := 0; < ; ++ { := .Out() := uintptr(.Align()) = ( + - 1) &^ ( - 1)if .Size() != 0 { := flagIndir | flag(.Kind()) [] = Value{.common(), add(, , "tv.Size() != 0"), }// Note: this does introduce false sharing between results - // if any result is live, they are all live. // (And the space for the args is live as well, but as we've // cleared that space it isn't as big a deal.) } else {// For zero-sized return value, args+off may point to the next object. // In this case, return the zero value instead. [] = Zero() } += .Size() } }return}// callReflect is the call implementation used by a function// returned by MakeFunc. In many ways it is the opposite of the// method Value.call above. The method above converts a call using Values// into a call of a function with a concrete argument frame, while// callReflect converts a call of a function with a concrete argument// frame into a call using Values.// It is in this file so that it can be next to the call method above.// The remainder of the MakeFunc implementation is in makefunc.go.//// NOTE: This function must be marked as a "wrapper" in the generated code,// so that the linker can make it work correctly for panic and recover.// The gc compilers know to do that for the name "reflect.callReflect".//// ctxt is the "closure" generated by MakeFunc.// frame is a pointer to the arguments to that closure on the stack.// retValid points to a boolean which should be set when the results// section of frame is set.func ( *makeFuncImpl, unsafe.Pointer, *bool) { := .ftyp := .fn// Copy argument frame into Values. := := uintptr(0) := make([]Value, 0, int(.inCount))for , := range .in() { += - & uintptr(.align-1) := Value{, nil, flag(.Kind())}ififaceIndir() {// value cannot be inlined in interface data. // Must make a copy, because f might keep a reference to it, // and we cannot let f keep a reference to the stack frame // after this function returns, not even a read-only reference. .ptr = unsafe_New()if .size > 0 {typedmemmove(, .ptr, add(, , "typ.size > 0")) } .flag |= flagIndir } else { .ptr = *(*unsafe.Pointer)(add(, , "1-ptr")) } = append(, ) += .size }// Call underlying function. := () := .NumOut()iflen() != {panic("reflect: wrong return count from function created by MakeFunc") }// Copy results back into argument frame.if > 0 { += - & (ptrSize - 1)for , := range .out() { := []if .typ == nil {panic("reflect: function created by MakeFunc using " + funcName() +" returned zero Value") }if .flag&flagRO != 0 {panic("reflect: function created by MakeFunc using " + funcName() +" returned value obtained from unexported field") } += - & uintptr(.align-1)if .size == 0 {continue } := add(, , "typ.size > 0")// Convert v to type typ if v is assignable to a variable // of type t in the language spec. // See issue 28761.if .Kind() == Interface {// We must clear the destination before calling assignTo, // in case assignTo writes (with memory barriers) to the // target location used as scratch space. See issue 39541. *(*uintptr)() = 0 *(*uintptr)(add(, ptrSize, "typ.size == 2*ptrSize")) = 0 } = .assignTo("reflect.MakeFunc", , )// We are writing to stack. No write barrier.if .flag&flagIndir != 0 {memmove(, .ptr, .size) } else { *(*uintptr)() = uintptr(.ptr) } += .size } }// Announce that the return values are valid. // After this point the runtime can depend on the return values being valid. * = true// We have to make sure that the out slice lives at least until // the runtime knows the return values are valid. Otherwise, the // return values might not be scanned by anyone during a GC. // (out would be dead, and the return slots not yet alive.)runtime.KeepAlive()// runtime.getArgInfo expects to be able to find ctxt on the // stack when it finds our caller, makeFuncStub. Make sure it // doesn't get garbage collected.runtime.KeepAlive()}// methodReceiver returns information about the receiver// described by v. The Value v may or may not have the// flagMethod bit set, so the kind cached in v.flag should// not be used.// The return value rcvrtype gives the method's actual receiver type.// The return value t gives the method type signature (without the receiver).// The return value fn is a pointer to the method code.func ( string, Value, int) ( *rtype, *funcType, unsafe.Pointer) { := if .typ.Kind() == Interface { := (*interfaceType)(unsafe.Pointer(.typ))ifuint() >= uint(len(.methods)) {panic("reflect: internal error: invalid method index") } := &.methods[]if !.nameOff(.name).isExported() {panic("reflect: " + + " of unexported method") } := (*nonEmptyInterface)(.ptr)if .itab == nil {panic("reflect: " + + " of method on nil interface value") } = .itab.typ = unsafe.Pointer(&.itab.fun[]) = (*funcType)(unsafe.Pointer(.typeOff(.typ))) } else { = .typ := .typ.exportedMethods()ifuint() >= uint(len()) {panic("reflect: internal error: invalid method index") } := []if !.typ.nameOff(.name).isExported() {panic("reflect: " + + " of unexported method") } := .typ.textOff(.ifn) = unsafe.Pointer(&) = (*funcType)(unsafe.Pointer(.typ.typeOff(.mtyp))) }return}// v is a method receiver. Store at p the word which is used to// encode that receiver at the start of the argument list.// Reflect uses the "interface" calling convention for// methods, which always uses one word to record the receiver.func ( Value, unsafe.Pointer) { := .typif .Kind() == Interface {// the interface data word becomes the receiver word := (*nonEmptyInterface)(.ptr) *(*unsafe.Pointer)() = .word } elseif .flag&flagIndir != 0 && !ifaceIndir() { *(*unsafe.Pointer)() = *(*unsafe.Pointer)(.ptr) } else { *(*unsafe.Pointer)() = .ptr }}// align returns the result of rounding x up to a multiple of n.// n must be a power of two.func (, uintptr) uintptr {return ( + - 1) &^ ( - 1)}// callMethod is the call implementation used by a function returned// by makeMethodValue (used by v.Method(i).Interface()).// It is a streamlined version of the usual reflect call: the caller has// already laid out the argument frame for us, so we don't have// to deal with individual Values for each argument.// It is in this file so that it can be next to the two similar functions above.// The remainder of the makeMethodValue implementation is in makefunc.go.//// NOTE: This function must be marked as a "wrapper" in the generated code,// so that the linker can make it work correctly for panic and recover.// The gc compilers know to do that for the name "reflect.callMethod".//// ctxt is the "closure" generated by makeVethodValue.// frame is a pointer to the arguments to that closure on the stack.// retValid points to a boolean which should be set when the results// section of frame is set.func ( *methodValue, unsafe.Pointer, *bool) { := .rcvr , , := methodReceiver("call", , .method) , , , , := funcLayout(, )// Make a new frame that is one word bigger so we can store the receiver. // This space is used for both arguments and return values. := .Get().(unsafe.Pointer)// Copy in receiver and rest of args.storeRcvr(, )// Align the first arg. The alignment can't be larger than ptrSize. := uintptr(ptrSize)iflen(.in()) > 0 { = align(, uintptr(.in()[0].align)) }// Avoid constructing out-of-bounds pointers if there are no args.if - > 0 {typedmemmovepartial(, add(, , "argSize > argOffset"), , , -) }// Call. // Call copies the arguments from scratch to the stack, calls fn, // and then copies the results back into scratch.call(, , , uint32(.size), uint32())// Copy return values. // Ignore any changes to args and just copy return values. // Avoid constructing out-of-bounds pointers if there are no return values.if .size- > 0 { := - // This copies to the stack. Write barriers are not needed.memmove(add(, , "frametype.size > retOffset"),add(, , "frametype.size > retOffset"), .size-) }// Tell the runtime it can now depend on the return values // being properly initialized. * = true// Clear the scratch space and put it back in the pool. // This must happen after the statement above, so that the return // values will always be scanned by someone.typedmemclr(, ) .Put()// See the comment in callReflect.runtime.KeepAlive()}// funcName returns the name of f, for use in error messages.func ( func([]Value) []Value) string { := *(*uintptr)(unsafe.Pointer(&)) := runtime.FuncForPC()if != nil {return .Name() }return"closure"}// Cap returns v's capacity.// It panics if v's Kind is not Array, Chan, or Slice.func ( Value) () int { := .kind()switch {caseArray:return .typ.Len()caseChan:returnchancap(.pointer())caseSlice:// Slice is always bigger than a word; assume flagIndir.return (*unsafeheader.Slice)(.ptr).Cap }panic(&ValueError{"reflect.Value.Cap", .kind()})}// Close closes the channel v.// It panics if v's Kind is not Chan.func ( Value) () { .mustBe(Chan) .mustBeExported()chanclose(.pointer())}// Complex returns v's underlying value, as a complex128.// It panics if v's Kind is not Complex64 or Complex128func ( Value) () complex128 { := .kind()switch {caseComplex64:returncomplex128(*(*complex64)(.ptr))caseComplex128:return *(*complex128)(.ptr) }panic(&ValueError{"reflect.Value.Complex", .kind()})}// Elem returns the value that the interface v contains// or that the pointer v points to.// It panics if v's Kind is not Interface or Ptr.// It returns the zero Value if v is nil.func ( Value) () Value { := .kind()switch {caseInterface:varinterface{}if .typ.NumMethod() == 0 { = *(*interface{})(.ptr) } else { = (interface{})(*(*interface { () })(.ptr)) } := unpackEface()if .flag != 0 { .flag |= .flag.ro() }returncasePtr: := .ptrif .flag&flagIndir != 0 { = *(*unsafe.Pointer)() }// The returned value's address is v's value.if == nil {returnValue{} } := (*ptrType)(unsafe.Pointer(.typ)) := .elem := .flag&flagRO | flagIndir | flagAddr |= flag(.Kind())returnValue{, , } }panic(&ValueError{"reflect.Value.Elem", .kind()})}// Field returns the i'th field of the struct v.// It panics if v's Kind is not Struct or i is out of range.func ( Value) ( int) Value {if .kind() != Struct {panic(&ValueError{"reflect.Value.Field", .kind()}) } := (*structType)(unsafe.Pointer(.typ))ifuint() >= uint(len(.fields)) {panic("reflect: Field index out of range") } := &.fields[] := .typ// Inherit permission bits from v, but clear flagEmbedRO. := .flag&(flagStickyRO|flagIndir|flagAddr) | flag(.Kind())// Using an unexported field forces flagRO.if !.name.isExported() {if .embedded() { |= flagEmbedRO } else { |= flagStickyRO } }// Either flagIndir is set and v.ptr points at struct, // or flagIndir is not set and v.ptr is the actual struct data. // In the former case, we want v.ptr + offset. // In the latter case, we must have field.offset = 0, // so v.ptr + field.offset is still the correct address. := add(.ptr, .offset(), "same as non-reflect &v.field")returnValue{, , }}// FieldByIndex returns the nested field corresponding to index.// It panics if v's Kind is not struct.func ( Value) ( []int) Value {iflen() == 1 {return .Field([0]) } .mustBe(Struct)for , := range {if > 0 {if .Kind() == Ptr && .typ.Elem().Kind() == Struct {if .IsNil() {panic("reflect: indirection through nil pointer to embedded struct") } = .Elem() } } = .Field() }return}// FieldByName returns the struct field with the given name.// It returns the zero Value if no field was found.// It panics if v's Kind is not struct.func ( Value) ( string) Value { .mustBe(Struct)if , := .typ.FieldByName(); {return .FieldByIndex(.Index) }returnValue{}}// FieldByNameFunc returns the struct field with a name// that satisfies the match function.// It panics if v's Kind is not struct.// It returns the zero Value if no field was found.func ( Value) ( func(string) bool) Value {if , := .typ.FieldByNameFunc(); {return .FieldByIndex(.Index) }returnValue{}}// Float returns v's underlying value, as a float64.// It panics if v's Kind is not Float32 or Float64func ( Value) () float64 { := .kind()switch {caseFloat32:returnfloat64(*(*float32)(.ptr))caseFloat64:return *(*float64)(.ptr) }panic(&ValueError{"reflect.Value.Float", .kind()})}varuint8Type = TypeOf(uint8(0)).(*rtype)// Index returns v's i'th element.// It panics if v's Kind is not Array, Slice, or String or i is out of range.func ( Value) ( int) Value {switch .kind() {caseArray: := (*arrayType)(unsafe.Pointer(.typ))ifuint() >= uint(.len) {panic("reflect: array index out of range") } := .elem := uintptr() * .size// Either flagIndir is set and v.ptr points at array, // or flagIndir is not set and v.ptr is the actual array data. // In the former case, we want v.ptr + offset. // In the latter case, we must be doing Index(0), so offset = 0, // so v.ptr + offset is still the correct address. := add(.ptr, , "same as &v[i], i < tt.len") := .flag&(flagIndir|flagAddr) | .flag.ro() | flag(.Kind()) // bits same as overall arrayreturnValue{, , }caseSlice:// Element flag same as Elem of Ptr. // Addressable, indirect, possibly read-only. := (*unsafeheader.Slice)(.ptr)ifuint() >= uint(.Len) {panic("reflect: slice index out of range") } := (*sliceType)(unsafe.Pointer(.typ)) := .elem := arrayAt(.Data, , .size, "i < s.Len") := flagAddr | flagIndir | .flag.ro() | flag(.Kind())returnValue{, , }caseString: := (*unsafeheader.String)(.ptr)ifuint() >= uint(.Len) {panic("reflect: string index out of range") } := arrayAt(.Data, , 1, "i < s.Len") := .flag.ro() | flag(Uint8) | flagIndirreturnValue{uint8Type, , } }panic(&ValueError{"reflect.Value.Index", .kind()})}// Int returns v's underlying value, as an int64.// It panics if v's Kind is not Int, Int8, Int16, Int32, or Int64.func ( Value) () int64 { := .kind() := .ptrswitch {caseInt:returnint64(*(*int)())caseInt8:returnint64(*(*int8)())caseInt16:returnint64(*(*int16)())caseInt32:returnint64(*(*int32)())caseInt64:return *(*int64)() }panic(&ValueError{"reflect.Value.Int", .kind()})}// CanInterface reports whether Interface can be used without panicking.func ( Value) () bool {if .flag == 0 {panic(&ValueError{"reflect.Value.CanInterface", Invalid}) }return .flag&flagRO == 0}// Interface returns v's current value as an interface{}.// It is equivalent to:// var i interface{} = (v's underlying value)// It panics if the Value was obtained by accessing// unexported struct fields.func ( Value) () ( interface{}) {returnvalueInterface(, true)}func ( Value, bool) interface{} {if .flag == 0 {panic(&ValueError{"reflect.Value.Interface", Invalid}) }if && .flag&flagRO != 0 {// Do not allow access to unexported values via Interface, // because they might be pointers that should not be // writable or methods or function that should not be callable.panic("reflect.Value.Interface: cannot return value obtained from unexported field or method") }if .flag&flagMethod != 0 { = makeMethodValue("Interface", ) }if .kind() == Interface {// Special case: return the element inside the interface. // Empty interface has one layout, all interfaces with // methods have a second layout.if .NumMethod() == 0 {return *(*interface{})(.ptr) }return *(*interface { () })(.ptr) }// TODO: pass safe to packEface so we don't need to copy if safe==true?returnpackEface()}// InterfaceData returns the interface v's value as a uintptr pair.// It panics if v's Kind is not Interface.func ( Value) () [2]uintptr {// TODO: deprecate this .mustBe(Interface)// We treat this as a read operation, so we allow // it even for unexported data, because the caller // has to import "unsafe" to turn it into something // that can be abused. // Interface value is always bigger than a word; assume flagIndir.return *(*[2]uintptr)(.ptr)}// IsNil reports whether its argument v is nil. The argument must be// a chan, func, interface, map, pointer, or slice value; if it is// not, IsNil panics. Note that IsNil is not always equivalent to a// regular comparison with nil in Go. For example, if v was created// by calling ValueOf with an uninitialized interface variable i,// i==nil will be true but v.IsNil will panic as v will be the zero// Value.func ( Value) () bool { := .kind()switch {caseChan, Func, Map, Ptr, UnsafePointer:if .flag&flagMethod != 0 {returnfalse } := .ptrif .flag&flagIndir != 0 { = *(*unsafe.Pointer)() }return == nilcaseInterface, Slice:// Both interface and slice are nil if first word is 0. // Both are always bigger than a word; assume flagIndir.return *(*unsafe.Pointer)(.ptr) == nil }panic(&ValueError{"reflect.Value.IsNil", .kind()})}// IsValid reports whether v represents a value.// It returns false if v is the zero Value.// If IsValid returns false, all other methods except String panic.// Most functions and methods never return an invalid Value.// If one does, its documentation states the conditions explicitly.func ( Value) () bool {return .flag != 0}// IsZero reports whether v is the zero value for its type.// It panics if the argument is invalid.func ( Value) () bool {switch .kind() {caseBool:return !.Bool()caseInt, Int8, Int16, Int32, Int64:return .Int() == 0caseUint, Uint8, Uint16, Uint32, Uint64, Uintptr:return .Uint() == 0caseFloat32, Float64:returnmath.Float64bits(.Float()) == 0caseComplex64, Complex128: := .Complex()returnmath.Float64bits(real()) == 0 && math.Float64bits(imag()) == 0caseArray:for := 0; < .Len(); ++ {if !.Index().() {returnfalse } }returntruecaseChan, Func, Interface, Map, Ptr, Slice, UnsafePointer:return .IsNil()caseString:return .Len() == 0caseStruct:for := 0; < .NumField(); ++ {if !.Field().() {returnfalse } }returntruedefault:// This should never happens, but will act as a safeguard for // later, as a default value doesn't makes sense here.panic(&ValueError{"reflect.Value.IsZero", .Kind()}) }}// Kind returns v's Kind.// If v is the zero Value (IsValid returns false), Kind returns Invalid.func ( Value) () Kind {return .kind()}// Len returns v's length.// It panics if v's Kind is not Array, Chan, Map, Slice, or String.func ( Value) () int { := .kind()switch {caseArray: := (*arrayType)(unsafe.Pointer(.typ))returnint(.len)caseChan:returnchanlen(.pointer())caseMap:returnmaplen(.pointer())caseSlice:// Slice is bigger than a word; assume flagIndir.return (*unsafeheader.Slice)(.ptr).LencaseString:// String is bigger than a word; assume flagIndir.return (*unsafeheader.String)(.ptr).Len }panic(&ValueError{"reflect.Value.Len", .kind()})}// MapIndex returns the value associated with key in the map v.// It panics if v's Kind is not Map.// It returns the zero Value if key is not found in the map or if v represents a nil map.// As in Go, the key's value must be assignable to the map's key type.func ( Value) ( Value) Value { .mustBe(Map) := (*mapType)(unsafe.Pointer(.typ))// Do not require key to be exported, so that DeepEqual // and other programs can use all the keys returned by // MapKeys as arguments to MapIndex. If either the map // or the key is unexported, though, the result will be // considered unexported. This is consistent with the // behavior for structs, which allow read but not write // of unexported fields. = .assignTo("reflect.Value.MapIndex", .key, nil)varunsafe.Pointerif .flag&flagIndir != 0 { = .ptr } else { = unsafe.Pointer(&.ptr) } := mapaccess(.typ, .pointer(), )if == nil {returnValue{} } := .elem := (.flag | .flag).ro() |= flag(.Kind())returncopyVal(, , )}// MapKeys returns a slice containing all the keys present in the map,// in unspecified order.// It panics if v's Kind is not Map.// It returns an empty slice if v represents a nil map.func ( Value) () []Value { .mustBe(Map) := (*mapType)(unsafe.Pointer(.typ)) := .key := .flag.ro() | flag(.Kind()) := .pointer() := int(0)if != nil { = maplen() } := mapiterinit(.typ, ) := make([]Value, )varintfor = 0; < len(); ++ { := mapiterkey()if == nil {// Someone deleted an entry from the map since we // called maplen above. It's a data race, but nothing // we can do about it.break } [] = copyVal(, , )mapiternext() }return [:]}// A MapIter is an iterator for ranging over a map.// See Value.MapRange.typeMapIterstruct { m Value it unsafe.Pointer}// Key returns the key of the iterator's current map entry.func ( *MapIter) () Value {if .it == nil {panic("MapIter.Key called before Next") }ifmapiterkey(.it) == nil {panic("MapIter.Key called on exhausted iterator") } := (*mapType)(unsafe.Pointer(.m.typ)) := .keyreturncopyVal(, .m.flag.ro()|flag(.Kind()), mapiterkey(.it))}// Value returns the value of the iterator's current map entry.func ( *MapIter) () Value {if .it == nil {panic("MapIter.Value called before Next") }ifmapiterkey(.it) == nil {panic("MapIter.Value called on exhausted iterator") } := (*mapType)(unsafe.Pointer(.m.typ)) := .elemreturncopyVal(, .m.flag.ro()|flag(.Kind()), mapiterelem(.it))}// Next advances the map iterator and reports whether there is another// entry. It returns false when the iterator is exhausted; subsequent// calls to Key, Value, or Next will panic.func ( *MapIter) () bool {if .it == nil { .it = mapiterinit(.m.typ, .m.pointer()) } else {ifmapiterkey(.it) == nil {panic("MapIter.Next called on exhausted iterator") }mapiternext(.it) }returnmapiterkey(.it) != nil}// MapRange returns a range iterator for a map.// It panics if v's Kind is not Map.//// Call Next to advance the iterator, and Key/Value to access each entry.// Next returns false when the iterator is exhausted.// MapRange follows the same iteration semantics as a range statement.//// Example://// iter := reflect.ValueOf(m).MapRange()// for iter.Next() {// k := iter.Key()// v := iter.Value()// ...// }//func ( Value) () *MapIter { .mustBe(Map)return &MapIter{m: }}// copyVal returns a Value containing the map key or value at ptr,// allocating a new variable as needed.func ( *rtype, flag, unsafe.Pointer) Value {ififaceIndir() {// Copy result so future changes to the map // won't change the underlying value. := unsafe_New()typedmemmove(, , )returnValue{, , | flagIndir} }returnValue{, *(*unsafe.Pointer)(), }}// Method returns a function value corresponding to v's i'th method.// The arguments to a Call on the returned function should not include// a receiver; the returned function will always use v as the receiver.// Method panics if i is out of range or if v is a nil interface value.func ( Value) ( int) Value {if .typ == nil {panic(&ValueError{"reflect.Value.Method", Invalid}) }if .flag&flagMethod != 0 || uint() >= uint(.typ.NumMethod()) {panic("reflect: Method index out of range") }if .typ.Kind() == Interface && .IsNil() {panic("reflect: Method on nil interface value") } := .flag.ro() | (.flag & flagIndir) |= flag(Func) |= flag()<<flagMethodShift | flagMethodreturnValue{.typ, .ptr, }}// NumMethod returns the number of exported methods in the value's method set.func ( Value) () int {if .typ == nil {panic(&ValueError{"reflect.Value.NumMethod", Invalid}) }if .flag&flagMethod != 0 {return0 }return .typ.NumMethod()}// MethodByName returns a function value corresponding to the method// of v with the given name.// The arguments to a Call on the returned function should not include// a receiver; the returned function will always use v as the receiver.// It returns the zero Value if no method was found.func ( Value) ( string) Value {if .typ == nil {panic(&ValueError{"reflect.Value.MethodByName", Invalid}) }if .flag&flagMethod != 0 {returnValue{} } , := .typ.MethodByName()if ! {returnValue{} }return .Method(.Index)}// NumField returns the number of fields in the struct v.// It panics if v's Kind is not Struct.func ( Value) () int { .mustBe(Struct) := (*structType)(unsafe.Pointer(.typ))returnlen(.fields)}// OverflowComplex reports whether the complex128 x cannot be represented by v's type.// It panics if v's Kind is not Complex64 or Complex128.func ( Value) ( complex128) bool { := .kind()switch {caseComplex64:returnoverflowFloat32(real()) || overflowFloat32(imag())caseComplex128:returnfalse }panic(&ValueError{"reflect.Value.OverflowComplex", .kind()})}// OverflowFloat reports whether the float64 x cannot be represented by v's type.// It panics if v's Kind is not Float32 or Float64.func ( Value) ( float64) bool { := .kind()switch {caseFloat32:returnoverflowFloat32()caseFloat64:returnfalse }panic(&ValueError{"reflect.Value.OverflowFloat", .kind()})}func ( float64) bool {if < 0 { = - }returnmath.MaxFloat32 < && <= math.MaxFloat64}// OverflowInt reports whether the int64 x cannot be represented by v's type.// It panics if v's Kind is not Int, Int8, Int16, Int32, or Int64.func ( Value) ( int64) bool { := .kind()switch {caseInt, Int8, Int16, Int32, Int64: := .typ.size * 8 := ( << (64 - )) >> (64 - )return != }panic(&ValueError{"reflect.Value.OverflowInt", .kind()})}// OverflowUint reports whether the uint64 x cannot be represented by v's type.// It panics if v's Kind is not Uint, Uintptr, Uint8, Uint16, Uint32, or Uint64.func ( Value) ( uint64) bool { := .kind()switch {caseUint, Uintptr, Uint8, Uint16, Uint32, Uint64: := .typ.size * 8 := ( << (64 - )) >> (64 - )return != }panic(&ValueError{"reflect.Value.OverflowUint", .kind()})}//go:nocheckptr// This prevents inlining Value.Pointer when -d=checkptr is enabled,// which ensures cmd/compile can recognize unsafe.Pointer(v.Pointer())// and make an exception.// Pointer returns v's value as a uintptr.// It returns uintptr instead of unsafe.Pointer so that// code using reflect cannot obtain unsafe.Pointers// without importing the unsafe package explicitly.// It panics if v's Kind is not Chan, Func, Map, Ptr, Slice, or UnsafePointer.//// If v's Kind is Func, the returned pointer is an underlying// code pointer, but not necessarily enough to identify a// single function uniquely. The only guarantee is that the// result is zero if and only if v is a nil func Value.//// If v's Kind is Slice, the returned pointer is to the first// element of the slice. If the slice is nil the returned value// is 0. If the slice is empty but non-nil the return value is non-zero.func ( Value) () uintptr {// TODO: deprecate := .kind()switch {casePtr:if .typ.ptrdata == 0 {// Handle pointers to go:notinheap types directly, // so we never materialize such pointers as an // unsafe.Pointer. (Such pointers are always indirect.) // See issue 42076.return *(*uintptr)(.ptr) }fallthroughcaseChan, Map, UnsafePointer:returnuintptr(.pointer())caseFunc:if .flag&flagMethod != 0 {// As the doc comment says, the returned pointer is an // underlying code pointer but not necessarily enough to // identify a single function uniquely. All method expressions // created via reflect have the same underlying code pointer, // so their Pointers are equal. The function used here must // match the one used in makeMethodValue. := methodValueCallreturn **(**uintptr)(unsafe.Pointer(&)) } := .pointer()// Non-nil func value points at data block. // First word of data block is actual code.if != nil { = *(*unsafe.Pointer)() }returnuintptr()caseSlice:return (*SliceHeader)(.ptr).Data }panic(&ValueError{"reflect.Value.Pointer", .kind()})}// Recv receives and returns a value from the channel v.// It panics if v's Kind is not Chan.// The receive blocks until a value is ready.// The boolean value ok is true if the value x corresponds to a send// on the channel, false if it is a zero value received because the channel is closed.func ( Value) () ( Value, bool) { .mustBe(Chan) .mustBeExported()return .recv(false)}// internal recv, possibly non-blocking (nb).// v is known to be a channel.func ( Value) ( bool) ( Value, bool) { := (*chanType)(unsafe.Pointer(.typ))ifChanDir(.dir)&RecvDir == 0 {panic("reflect: recv on send-only channel") } := .elem = Value{, nil, flag(.Kind())}varunsafe.PointerififaceIndir() { = unsafe_New() .ptr = .flag |= flagIndir } else { = unsafe.Pointer(&.ptr) } , := chanrecv(.pointer(), , )if ! { = Value{} }return}// Send sends x on the channel v.// It panics if v's kind is not Chan or if x's type is not the same type as v's element type.// As in Go, x's value must be assignable to the channel's element type.func ( Value) ( Value) { .mustBe(Chan) .mustBeExported() .send(, false)}// internal send, possibly non-blocking.// v is known to be a channel.func ( Value) ( Value, bool) ( bool) { := (*chanType)(unsafe.Pointer(.typ))ifChanDir(.dir)&SendDir == 0 {panic("reflect: send on recv-only channel") } .mustBeExported() = .assignTo("reflect.Value.Send", .elem, nil)varunsafe.Pointerif .flag&flagIndir != 0 { = .ptr } else { = unsafe.Pointer(&.ptr) }returnchansend(.pointer(), , )}// Set assigns x to the value v.// It panics if CanSet returns false.// As in Go, x's value must be assignable to v's type.func ( Value) ( Value) { .mustBeAssignable() .mustBeExported() // do not let unexported x leakvarunsafe.Pointerif .kind() == Interface { = .ptr } = .assignTo("reflect.Set", .typ, )if .flag&flagIndir != 0 {if .ptr == unsafe.Pointer(&zeroVal[0]) {typedmemclr(.typ, .ptr) } else {typedmemmove(.typ, .ptr, .ptr) } } else { *(*unsafe.Pointer)(.ptr) = .ptr }}// SetBool sets v's underlying value.// It panics if v's Kind is not Bool or if CanSet() is false.func ( Value) ( bool) { .mustBeAssignable() .mustBe(Bool) *(*bool)(.ptr) = }// SetBytes sets v's underlying value.// It panics if v's underlying value is not a slice of bytes.func ( Value) ( []byte) { .mustBeAssignable() .mustBe(Slice)if .typ.Elem().Kind() != Uint8 {panic("reflect.Value.SetBytes of non-byte slice") } *(*[]byte)(.ptr) = }// setRunes sets v's underlying value.// It panics if v's underlying value is not a slice of runes (int32s).func ( Value) ( []rune) { .mustBeAssignable() .mustBe(Slice)if .typ.Elem().Kind() != Int32 {panic("reflect.Value.setRunes of non-rune slice") } *(*[]rune)(.ptr) = }// SetComplex sets v's underlying value to x.// It panics if v's Kind is not Complex64 or Complex128, or if CanSet() is false.func ( Value) ( complex128) { .mustBeAssignable()switch := .kind(); {default:panic(&ValueError{"reflect.Value.SetComplex", .kind()})caseComplex64: *(*complex64)(.ptr) = complex64()caseComplex128: *(*complex128)(.ptr) = }}// SetFloat sets v's underlying value to x.// It panics if v's Kind is not Float32 or Float64, or if CanSet() is false.func ( Value) ( float64) { .mustBeAssignable()switch := .kind(); {default:panic(&ValueError{"reflect.Value.SetFloat", .kind()})caseFloat32: *(*float32)(.ptr) = float32()caseFloat64: *(*float64)(.ptr) = }}// SetInt sets v's underlying value to x.// It panics if v's Kind is not Int, Int8, Int16, Int32, or Int64, or if CanSet() is false.func ( Value) ( int64) { .mustBeAssignable()switch := .kind(); {default:panic(&ValueError{"reflect.Value.SetInt", .kind()})caseInt: *(*int)(.ptr) = int()caseInt8: *(*int8)(.ptr) = int8()caseInt16: *(*int16)(.ptr) = int16()caseInt32: *(*int32)(.ptr) = int32()caseInt64: *(*int64)(.ptr) = }}// SetLen sets v's length to n.// It panics if v's Kind is not Slice or if n is negative or// greater than the capacity of the slice.func ( Value) ( int) { .mustBeAssignable() .mustBe(Slice) := (*unsafeheader.Slice)(.ptr)ifuint() > uint(.Cap) {panic("reflect: slice length out of range in SetLen") } .Len = }// SetCap sets v's capacity to n.// It panics if v's Kind is not Slice or if n is smaller than the length or// greater than the capacity of the slice.func ( Value) ( int) { .mustBeAssignable() .mustBe(Slice) := (*unsafeheader.Slice)(.ptr)if < .Len || > .Cap {panic("reflect: slice capacity out of range in SetCap") } .Cap = }// SetMapIndex sets the element associated with key in the map v to elem.// It panics if v's Kind is not Map.// If elem is the zero Value, SetMapIndex deletes the key from the map.// Otherwise if v holds a nil map, SetMapIndex will panic.// As in Go, key's elem must be assignable to the map's key type,// and elem's value must be assignable to the map's elem type.func ( Value) (, Value) { .mustBe(Map) .mustBeExported() .mustBeExported() := (*mapType)(unsafe.Pointer(.typ)) = .assignTo("reflect.Value.SetMapIndex", .key, nil)varunsafe.Pointerif .flag&flagIndir != 0 { = .ptr } else { = unsafe.Pointer(&.ptr) }if .typ == nil {mapdelete(.typ, .pointer(), )return } .mustBeExported() = .assignTo("reflect.Value.SetMapIndex", .elem, nil)varunsafe.Pointerif .flag&flagIndir != 0 { = .ptr } else { = unsafe.Pointer(&.ptr) }mapassign(.typ, .pointer(), , )}// SetUint sets v's underlying value to x.// It panics if v's Kind is not Uint, Uintptr, Uint8, Uint16, Uint32, or Uint64, or if CanSet() is false.func ( Value) ( uint64) { .mustBeAssignable()switch := .kind(); {default:panic(&ValueError{"reflect.Value.SetUint", .kind()})caseUint: *(*uint)(.ptr) = uint()caseUint8: *(*uint8)(.ptr) = uint8()caseUint16: *(*uint16)(.ptr) = uint16()caseUint32: *(*uint32)(.ptr) = uint32()caseUint64: *(*uint64)(.ptr) = caseUintptr: *(*uintptr)(.ptr) = uintptr() }}// SetPointer sets the unsafe.Pointer value v to x.// It panics if v's Kind is not UnsafePointer.func ( Value) ( unsafe.Pointer) { .mustBeAssignable() .mustBe(UnsafePointer) *(*unsafe.Pointer)(.ptr) = }// SetString sets v's underlying value to x.// It panics if v's Kind is not String or if CanSet() is false.func ( Value) ( string) { .mustBeAssignable() .mustBe(String) *(*string)(.ptr) = }// Slice returns v[i:j].// It panics if v's Kind is not Array, Slice or String, or if v is an unaddressable array,// or if the indexes are out of bounds.func ( Value) (, int) Value {var (int *sliceTypeunsafe.Pointer )switch := .kind(); {default:panic(&ValueError{"reflect.Value.Slice", .kind()})caseArray:if .flag&flagAddr == 0 {panic("reflect.Value.Slice: slice of unaddressable array") } := (*arrayType)(unsafe.Pointer(.typ)) = int(.len) = (*sliceType)(unsafe.Pointer(.slice)) = .ptrcaseSlice: = (*sliceType)(unsafe.Pointer(.typ)) := (*unsafeheader.Slice)(.ptr) = .Data = .CapcaseString: := (*unsafeheader.String)(.ptr)if < 0 || < || > .Len {panic("reflect.Value.Slice: string slice index out of bounds") }varunsafeheader.Stringif < .Len { = unsafeheader.String{Data: arrayAt(.Data, , 1, "i < s.Len"), Len: - } }returnValue{.typ, unsafe.Pointer(&), .flag} }if < 0 || < || > {panic("reflect.Value.Slice: slice index out of bounds") }// Declare slice so that gc can see the base pointer in it.var []unsafe.Pointer// Reinterpret as *unsafeheader.Slice to edit. := (*unsafeheader.Slice)(unsafe.Pointer(&)) .Len = - .Cap = - if - > 0 { .Data = arrayAt(, , .elem.Size(), "i < cap") } else {// do not advance pointer, to avoid pointing beyond end of slice .Data = } := .flag.ro() | flagIndir | flag(Slice)returnValue{.common(), unsafe.Pointer(&), }}// Slice3 is the 3-index form of the slice operation: it returns v[i:j:k].// It panics if v's Kind is not Array or Slice, or if v is an unaddressable array,// or if the indexes are out of bounds.func ( Value) (, , int) Value {var (int *sliceTypeunsafe.Pointer )switch := .kind(); {default:panic(&ValueError{"reflect.Value.Slice3", .kind()})caseArray:if .flag&flagAddr == 0 {panic("reflect.Value.Slice3: slice of unaddressable array") } := (*arrayType)(unsafe.Pointer(.typ)) = int(.len) = (*sliceType)(unsafe.Pointer(.slice)) = .ptrcaseSlice: = (*sliceType)(unsafe.Pointer(.typ)) := (*unsafeheader.Slice)(.ptr) = .Data = .Cap }if < 0 || < || < || > {panic("reflect.Value.Slice3: slice index out of bounds") }// Declare slice so that the garbage collector // can see the base pointer in it.var []unsafe.Pointer// Reinterpret as *unsafeheader.Slice to edit. := (*unsafeheader.Slice)(unsafe.Pointer(&)) .Len = - .Cap = - if - > 0 { .Data = arrayAt(, , .elem.Size(), "i < k <= cap") } else {// do not advance pointer, to avoid pointing beyond end of slice .Data = } := .flag.ro() | flagIndir | flag(Slice)returnValue{.common(), unsafe.Pointer(&), }}// String returns the string v's underlying value, as a string.// String is a special case because of Go's String method convention.// Unlike the other getters, it does not panic if v's Kind is not String.// Instead, it returns a string of the form "<T value>" where T is v's type.// The fmt package treats Values specially. It does not call their String// method implicitly but instead prints the concrete values they hold.func ( Value) () string {switch := .kind(); {caseInvalid:return"<invalid Value>"caseString:return *(*string)(.ptr) }// If you call String on a reflect.Value of other type, it's better to // print something than to panic. Useful in debugging.return"<" + .Type().String() + " Value>"}// TryRecv attempts to receive a value from the channel v but will not block.// It panics if v's Kind is not Chan.// If the receive delivers a value, x is the transferred value and ok is true.// If the receive cannot finish without blocking, x is the zero Value and ok is false.// If the channel is closed, x is the zero value for the channel's element type and ok is false.func ( Value) () ( Value, bool) { .mustBe(Chan) .mustBeExported()return .recv(true)}// TrySend attempts to send x on the channel v but will not block.// It panics if v's Kind is not Chan.// It reports whether the value was sent.// As in Go, x's value must be assignable to the channel's element type.func ( Value) ( Value) bool { .mustBe(Chan) .mustBeExported()return .send(, true)}// Type returns v's type.func ( Value) () Type { := .flagif == 0 {panic(&ValueError{"reflect.Value.Type", Invalid}) }if &flagMethod == 0 {// Easy casereturn .typ }// Method value. // v.typ describes the receiver, not the method type. := int(.flag) >> flagMethodShiftif .typ.Kind() == Interface {// Method on interface. := (*interfaceType)(unsafe.Pointer(.typ))ifuint() >= uint(len(.methods)) {panic("reflect: internal error: invalid method index") } := &.methods[]return .typ.typeOff(.typ) }// Method on concrete type. := .typ.exportedMethods()ifuint() >= uint(len()) {panic("reflect: internal error: invalid method index") } := []return .typ.typeOff(.mtyp)}// Uint returns v's underlying value, as a uint64.// It panics if v's Kind is not Uint, Uintptr, Uint8, Uint16, Uint32, or Uint64.func ( Value) () uint64 { := .kind() := .ptrswitch {caseUint:returnuint64(*(*uint)())caseUint8:returnuint64(*(*uint8)())caseUint16:returnuint64(*(*uint16)())caseUint32:returnuint64(*(*uint32)())caseUint64:return *(*uint64)()caseUintptr:returnuint64(*(*uintptr)()) }panic(&ValueError{"reflect.Value.Uint", .kind()})}//go:nocheckptr// This prevents inlining Value.UnsafeAddr when -d=checkptr is enabled,// which ensures cmd/compile can recognize unsafe.Pointer(v.UnsafeAddr())// and make an exception.// UnsafeAddr returns a pointer to v's data.// It is for advanced clients that also import the "unsafe" package.// It panics if v is not addressable.func ( Value) () uintptr {// TODO: deprecateif .typ == nil {panic(&ValueError{"reflect.Value.UnsafeAddr", Invalid}) }if .flag&flagAddr == 0 {panic("reflect.Value.UnsafeAddr of unaddressable value") }returnuintptr(.ptr)}// StringHeader is the runtime representation of a string.// It cannot be used safely or portably and its representation may// change in a later release.// Moreover, the Data field is not sufficient to guarantee the data// it references will not be garbage collected, so programs must keep// a separate, correctly typed pointer to the underlying data.typeStringHeaderstruct { Data uintptr Len int}// SliceHeader is the runtime representation of a slice.// It cannot be used safely or portably and its representation may// change in a later release.// Moreover, the Data field is not sufficient to guarantee the data// it references will not be garbage collected, so programs must keep// a separate, correctly typed pointer to the underlying data.typeSliceHeaderstruct { Data uintptr Len int Cap int}func ( string, , Type) {if != {panic( + ": " + .String() + " != " + .String()) }}// arrayAt returns the i-th element of p,// an array whose elements are eltSize bytes wide.// The array pointed at by p must have at least i+1 elements:// it is invalid (but impossible to check here) to pass i >= len,// because then the result will point outside the array.// whySafe must explain why i < len. (Passing "i < len" is fine;// the benefit is to surface this assumption at the call site.)func ( unsafe.Pointer, int, uintptr, string) unsafe.Pointer {returnadd(, uintptr()*, "i < len")}// grow grows the slice s so that it can hold extra more values, allocating// more capacity if needed. It also returns the old and new slice lengths.func ( Value, int) (Value, int, int) { := .Len() := + if < {panic("reflect.Append: slice overflow") } := .Cap()if <= {return .Slice(0, ), , }if == 0 { = } else {for < {if < 1024 { += } else { += / 4 } } } := MakeSlice(.Type(), , )Copy(, )return , , }// Append appends the values x to a slice s and returns the resulting slice.// As in Go, each x's value must be assignable to the slice's element type.func ( Value, ...Value) Value { .mustBe(Slice) , , := grow(, len())for , := , 0; < ; , = +1, +1 { .Index().Set([]) }return}// AppendSlice appends a slice t to a slice s and returns the resulting slice.// The slices s and t must have the same element type.func (, Value) Value { .mustBe(Slice) .mustBe(Slice)typesMustMatch("reflect.AppendSlice", .Type().Elem(), .Type().Elem()) , , := grow(, .Len())Copy(.Slice(, ), )return}// Copy copies the contents of src into dst until either// dst has been filled or src has been exhausted.// It returns the number of elements copied.// Dst and src each must have kind Slice or Array, and// dst and src must have the same element type.//// As a special case, src can have kind String if the element type of dst is kind Uint8.func (, Value) int { := .kind()if != Array && != Slice {panic(&ValueError{"reflect.Copy", }) }if == Array { .mustBeAssignable() } .mustBeExported() := .kind()varboolif != Array && != Slice { = == String && .typ.Elem().Kind() == Uint8if ! {panic(&ValueError{"reflect.Copy", }) } } .mustBeExported() := .typ.Elem()if ! { := .typ.Elem()typesMustMatch("reflect.Copy", , ) }var , unsafeheader.Sliceif == Array { .Data = .ptr .Len = .Len() .Cap = .Len } else { = *(*unsafeheader.Slice)(.ptr) }if == Array { .Data = .ptr .Len = .Len() .Cap = .Len } elseif == Slice { = *(*unsafeheader.Slice)(.ptr) } else { := *(*unsafeheader.String)(.ptr) .Data = .Data .Len = .Len .Cap = .Len }returntypedslicecopy(.common(), , )}// A runtimeSelect is a single case passed to rselect.// This must match ../runtime/select.go:/runtimeSelecttyperuntimeSelectstruct { dir SelectDir// SelectSend, SelectRecv or SelectDefault typ *rtype// channel type ch unsafe.Pointer// channel val unsafe.Pointer// ptr to data (SendDir) or ptr to receive buffer (RecvDir)}// rselect runs a select. It returns the index of the chosen case.// If the case was a receive, val is filled in with the received value.// The conventional OK bool indicates whether the receive corresponds// to a sent value.//go:noescapefunc ([]runtimeSelect) ( int, bool)// A SelectDir describes the communication direction of a select case.typeSelectDirint// NOTE: These values must match ../runtime/select.go:/selectDir.const ( _ SelectDir = iotaSelectSend// case Chan <- SendSelectRecv// case <-Chan:SelectDefault// default)// A SelectCase describes a single case in a select operation.// The kind of case depends on Dir, the communication direction.//// If Dir is SelectDefault, the case represents a default case.// Chan and Send must be zero Values.//// If Dir is SelectSend, the case represents a send operation.// Normally Chan's underlying value must be a channel, and Send's underlying value must be// assignable to the channel's element type. As a special case, if Chan is a zero Value,// then the case is ignored, and the field Send will also be ignored and may be either zero// or non-zero.//// If Dir is SelectRecv, the case represents a receive operation.// Normally Chan's underlying value must be a channel and Send must be a zero Value.// If Chan is a zero Value, then the case is ignored, but Send must still be a zero Value.// When a receive operation is selected, the received Value is returned by Select.//typeSelectCasestruct { Dir SelectDir// direction of case Chan Value// channel to use (for send or receive) Send Value// value to send (for send)}// Select executes a select operation described by the list of cases.// Like the Go select statement, it blocks until at least one of the cases// can proceed, makes a uniform pseudo-random choice,// and then executes that case. It returns the index of the chosen case// and, if that case was a receive operation, the value received and a// boolean indicating whether the value corresponds to a send on the channel// (as opposed to a zero value received because the channel is closed).// Select supports a maximum of 65536 cases.func ( []SelectCase) ( int, Value, bool) {iflen() > 65536 {panic("reflect.Select: too many cases (max 65536)") }// NOTE: Do not trust that caller is not modifying cases data underfoot. // The range is safe because the caller cannot modify our copy of the len // and each iteration makes its own copy of the value c.var []runtimeSelectiflen() > 4 {// Slice is heap allocated due to runtime dependent capacity. = make([]runtimeSelect, len()) } else {// Slice can be stack allocated due to constant capacity. = make([]runtimeSelect, len(), 4) } := falsefor , := range { := &[] .dir = .Dirswitch .Dir {default:panic("reflect.Select: invalid Dir")caseSelectDefault: // defaultif {panic("reflect.Select: multiple default cases") } = trueif .Chan.IsValid() {panic("reflect.Select: default case has Chan value") }if .Send.IsValid() {panic("reflect.Select: default case has Send value") }caseSelectSend: := .Chanif !.IsValid() {break } .mustBe(Chan) .mustBeExported() := (*chanType)(unsafe.Pointer(.typ))ifChanDir(.dir)&SendDir == 0 {panic("reflect.Select: SendDir case using recv-only channel") } .ch = .pointer() .typ = &.rtype := .Sendif !.IsValid() {panic("reflect.Select: SendDir case missing Send value") } .mustBeExported() = .assignTo("reflect.Select", .elem, nil)if .flag&flagIndir != 0 { .val = .ptr } else { .val = unsafe.Pointer(&.ptr) }caseSelectRecv:if .Send.IsValid() {panic("reflect.Select: RecvDir case has Send value") } := .Chanif !.IsValid() {break } .mustBe(Chan) .mustBeExported() := (*chanType)(unsafe.Pointer(.typ))ifChanDir(.dir)&RecvDir == 0 {panic("reflect.Select: RecvDir case using send-only channel") } .ch = .pointer() .typ = &.rtype .val = unsafe_New(.elem) } } , = rselect()if [].dir == SelectRecv { := (*chanType)(unsafe.Pointer([].typ)) := .elem := [].val := flag(.Kind())ififaceIndir() { = Value{, , | flagIndir} } else { = Value{, *(*unsafe.Pointer)(), } } }return , , }/* * constructors */// implemented in package runtimefunc (*rtype) unsafe.Pointerfunc (*rtype, int) unsafe.Pointer// MakeSlice creates a new zero-initialized slice value// for the specified slice type, length, and capacity.func ( Type, , int) Value {if .Kind() != Slice {panic("reflect.MakeSlice of non-slice type") }if < 0 {panic("reflect.MakeSlice: negative len") }if < 0 {panic("reflect.MakeSlice: negative cap") }if > {panic("reflect.MakeSlice: len > cap") } := unsafeheader.Slice{Data: unsafe_NewArray(.Elem().(*rtype), ), Len: , Cap: }returnValue{.(*rtype), unsafe.Pointer(&), flagIndir | flag(Slice)}}// MakeChan creates a new channel with the specified type and buffer size.func ( Type, int) Value {if .Kind() != Chan {panic("reflect.MakeChan of non-chan type") }if < 0 {panic("reflect.MakeChan: negative buffer size") }if .ChanDir() != BothDir {panic("reflect.MakeChan: unidirectional channel type") } := .(*rtype) := makechan(, )returnValue{, , flag(Chan)}}// MakeMap creates a new map with the specified type.func ( Type) Value {returnMakeMapWithSize(, 0)}// MakeMapWithSize creates a new map with the specified type// and initial space for approximately n elements.func ( Type, int) Value {if .Kind() != Map {panic("reflect.MakeMapWithSize of non-map type") } := .(*rtype) := makemap(, )returnValue{, , flag(Map)}}// Indirect returns the value that v points to.// If v is a nil pointer, Indirect returns a zero Value.// If v is not a pointer, Indirect returns v.func ( Value) Value {if .Kind() != Ptr {return }return .Elem()}// ValueOf returns a new Value initialized to the concrete value// stored in the interface i. ValueOf(nil) returns the zero Value.func ( interface{}) Value {if == nil {returnValue{} }// TODO: Maybe allow contents of a Value to live on the stack. // For now we make the contents always escape to the heap. It // makes life easier in a few places (see chanrecv/mapassign // comment below).escapes()returnunpackEface()}// Zero returns a Value representing the zero value for the specified type.// The result is different from the zero value of the Value struct,// which represents no value at all.// For example, Zero(TypeOf(42)) returns a Value with Kind Int and value 0.// The returned value is neither addressable nor settable.func ( Type) Value {if == nil {panic("reflect: Zero(nil)") } := .(*rtype) := flag(.Kind())ififaceIndir() {varunsafe.Pointerif .size <= maxZero { = unsafe.Pointer(&zeroVal[0]) } else { = unsafe_New() }returnValue{, , | flagIndir} }returnValue{, nil, }}// must match declarations in runtime/map.go.constmaxZero = 1024//go:linkname zeroVal runtime.zeroValvarzeroVal [maxZero]byte// New returns a Value representing a pointer to a new zero value// for the specified type. That is, the returned Value's Type is PtrTo(typ).func ( Type) Value {if == nil {panic("reflect: New(nil)") } := .(*rtype) := unsafe_New() := flag(Ptr)returnValue{.ptrTo(), , }}// NewAt returns a Value representing a pointer to a value of the// specified type, using p as that pointer.func ( Type, unsafe.Pointer) Value { := flag(Ptr) := .(*rtype)returnValue{.ptrTo(), , }}// assignTo returns a value v that can be assigned directly to typ.// It panics if v is not assignable to typ.// For a conversion to an interface type, target is a suggested scratch space to use.// target must be initialized memory (or nil).func ( Value) ( string, *rtype, unsafe.Pointer) Value {if .flag&flagMethod != 0 { = makeMethodValue(, ) }switch {casedirectlyAssignable(, .typ):// Overwrite type so that they match. // Same memory layout, so no harm done. := .flag&(flagAddr|flagIndir) | .flag.ro() |= flag(.Kind())returnValue{, .ptr, }caseimplements(, .typ):if == nil { = unsafe_New() }if .Kind() == Interface && .IsNil() {// A nil ReadWriter passed to nil Reader is OK, // but using ifaceE2I below will panic. // Avoid the panic by returning a nil dst (e.g., Reader) explicitly.returnValue{, nil, flag(Interface)} } := valueInterface(, false)if .NumMethod() == 0 { *(*interface{})() = } else {ifaceE2I(, , ) }returnValue{, , flagIndir | flag(Interface)} }// Failed.panic( + ": value of type " + .typ.String() + " is not assignable to type " + .String())}// Convert returns the value v converted to type t.// If the usual Go conversion rules do not allow conversion// of the value v to type t, Convert panics.func ( Value) ( Type) Value {if .flag&flagMethod != 0 { = makeMethodValue("Convert", ) } := convertOp(.common(), .typ)if == nil {panic("reflect.Value.Convert: value of type " + .typ.String() + " cannot be converted to type " + .String()) }return (, )}// convertOp returns the function to convert a value of type src// to a value of type dst. If the conversion is illegal, convertOp returns nil.func (, *rtype) func(Value, Type) Value {switch .Kind() {caseInt, Int8, Int16, Int32, Int64:switch .Kind() {caseInt, Int8, Int16, Int32, Int64, Uint, Uint8, Uint16, Uint32, Uint64, Uintptr:returncvtIntcaseFloat32, Float64:returncvtIntFloatcaseString:returncvtIntString }caseUint, Uint8, Uint16, Uint32, Uint64, Uintptr:switch .Kind() {caseInt, Int8, Int16, Int32, Int64, Uint, Uint8, Uint16, Uint32, Uint64, Uintptr:returncvtUintcaseFloat32, Float64:returncvtUintFloatcaseString:returncvtUintString }caseFloat32, Float64:switch .Kind() {caseInt, Int8, Int16, Int32, Int64:returncvtFloatIntcaseUint, Uint8, Uint16, Uint32, Uint64, Uintptr:returncvtFloatUintcaseFloat32, Float64:returncvtFloat }caseComplex64, Complex128:switch .Kind() {caseComplex64, Complex128:returncvtComplex }caseString:if .Kind() == Slice && .Elem().PkgPath() == "" {switch .Elem().Kind() {caseUint8:returncvtStringBytescaseInt32:returncvtStringRunes } }caseSlice:if .Kind() == String && .Elem().PkgPath() == "" {switch .Elem().Kind() {caseUint8:returncvtBytesStringcaseInt32:returncvtRunesString } }caseChan:if .Kind() == Chan && specialChannelAssignability(, ) {returncvtDirect } }// dst and src have same underlying type.ifhaveIdenticalUnderlyingType(, , false) {returncvtDirect }// dst and src are non-defined pointer types with same underlying base type.if .Kind() == Ptr && .Name() == "" && .Kind() == Ptr && .Name() == "" &&haveIdenticalUnderlyingType(.Elem().common(), .Elem().common(), false) {returncvtDirect }ifimplements(, ) {if .Kind() == Interface {returncvtI2I }returncvtT2I }returnnil}// makeInt returns a Value of type t equal to bits (possibly truncated),// where t is a signed or unsigned int type.func ( flag, uint64, Type) Value { := .common() := unsafe_New()switch .size {case1: *(*uint8)() = uint8()case2: *(*uint16)() = uint16()case4: *(*uint32)() = uint32()case8: *(*uint64)() = }returnValue{, , | flagIndir | flag(.Kind())}}// makeFloat returns a Value of type t equal to v (possibly truncated to float32),// where t is a float32 or float64 type.func ( flag, float64, Type) Value { := .common() := unsafe_New()switch .size {case4: *(*float32)() = float32()case8: *(*float64)() = }returnValue{, , | flagIndir | flag(.Kind())}}// makeFloat returns a Value of type t equal to v, where t is a float32 type.func ( flag, float32, Type) Value { := .common() := unsafe_New() *(*float32)() = returnValue{, , | flagIndir | flag(.Kind())}}// makeComplex returns a Value of type t equal to v (possibly truncated to complex64),// where t is a complex64 or complex128 type.func ( flag, complex128, Type) Value { := .common() := unsafe_New()switch .size {case8: *(*complex64)() = complex64()case16: *(*complex128)() = }returnValue{, , | flagIndir | flag(.Kind())}}func ( flag, string, Type) Value { := New().Elem() .SetString() .flag = .flag&^flagAddr | return}func ( flag, []byte, Type) Value { := New().Elem() .SetBytes() .flag = .flag&^flagAddr | return}func ( flag, []rune, Type) Value { := New().Elem() .setRunes() .flag = .flag&^flagAddr | return}// These conversion functions are returned by convertOp// for classes of conversions. For example, the first function, cvtInt,// takes any value v of signed int type and returns the value converted// to type t, where t is any signed or unsigned int type.// convertOp: intXX -> [u]intXXfunc ( Value, Type) Value {returnmakeInt(.flag.ro(), uint64(.Int()), )}// convertOp: uintXX -> [u]intXXfunc ( Value, Type) Value {returnmakeInt(.flag.ro(), .Uint(), )}// convertOp: floatXX -> intXXfunc ( Value, Type) Value {returnmakeInt(.flag.ro(), uint64(int64(.Float())), )}// convertOp: floatXX -> uintXXfunc ( Value, Type) Value {returnmakeInt(.flag.ro(), uint64(.Float()), )}// convertOp: intXX -> floatXXfunc ( Value, Type) Value {returnmakeFloat(.flag.ro(), float64(.Int()), )}// convertOp: uintXX -> floatXXfunc ( Value, Type) Value {returnmakeFloat(.flag.ro(), float64(.Uint()), )}// convertOp: floatXX -> floatXXfunc ( Value, Type) Value {if .Type().Kind() == Float32 && .Kind() == Float32 {// Don't do any conversion if both types have underlying type float32. // This avoids converting to float64 and back, which will // convert a signaling NaN to a quiet NaN. See issue 36400.returnmakeFloat32(.flag.ro(), *(*float32)(.ptr), ) }returnmakeFloat(.flag.ro(), .Float(), )}// convertOp: complexXX -> complexXXfunc ( Value, Type) Value {returnmakeComplex(.flag.ro(), .Complex(), )}// convertOp: intXX -> stringfunc ( Value, Type) Value { := "\uFFFD"if := .Int(); int64(rune()) == { = string(rune()) }returnmakeString(.flag.ro(), , )}// convertOp: uintXX -> stringfunc ( Value, Type) Value { := "\uFFFD"if := .Uint(); uint64(rune()) == { = string(rune()) }returnmakeString(.flag.ro(), , )}// convertOp: []byte -> stringfunc ( Value, Type) Value {returnmakeString(.flag.ro(), string(.Bytes()), )}// convertOp: string -> []bytefunc ( Value, Type) Value {returnmakeBytes(.flag.ro(), []byte(.String()), )}// convertOp: []rune -> stringfunc ( Value, Type) Value {returnmakeString(.flag.ro(), string(.runes()), )}// convertOp: string -> []runefunc ( Value, Type) Value {returnmakeRunes(.flag.ro(), []rune(.String()), )}// convertOp: direct copyfunc ( Value, Type) Value { := .flag := .common() := .ptrif &flagAddr != 0 {// indirect, mutable word - make a copy := unsafe_New()typedmemmove(, , ) = &^= flagAddr }returnValue{, , .flag.ro() | } // v.flag.ro()|f == f?}// convertOp: concrete -> interfacefunc ( Value, Type) Value { := unsafe_New(.common()) := valueInterface(, false)if .NumMethod() == 0 { *(*interface{})() = } else {ifaceE2I(.(*rtype), , ) }returnValue{.common(), , .flag.ro() | flagIndir | flag(Interface)}}// convertOp: interface -> interfacefunc ( Value, Type) Value {if .IsNil() { := Zero() .flag |= .flag.ro()return }returncvtT2I(.Elem(), )}// implemented in ../runtimefunc ( unsafe.Pointer) intfunc ( unsafe.Pointer)func ( unsafe.Pointer) int// Note: some of the noescape annotations below are technically a lie,// but safe in the context of this package. Functions like chansend// and mapassign don't escape the referent, but may escape anything// the referent points to (they do shallow copies of the referent).// It is safe in this package because the referent may only point// to something a Value may point to, and that is always in the heap// (due to the escapes() call in ValueOf).//go:noescapefunc ( unsafe.Pointer, bool, unsafe.Pointer) (, bool)//go:noescapefunc ( unsafe.Pointer, unsafe.Pointer, bool) boolfunc ( *rtype, int) ( unsafe.Pointer)func ( *rtype, int) ( unsafe.Pointer)//go:noescapefunc ( *rtype, unsafe.Pointer, unsafe.Pointer) ( unsafe.Pointer)//go:noescapefunc ( *rtype, unsafe.Pointer, , unsafe.Pointer)//go:noescapefunc ( *rtype, unsafe.Pointer, unsafe.Pointer)// m escapes into the return value, but the caller of mapiterinit// doesn't let the return value escape.//go:noescapefunc ( *rtype, unsafe.Pointer) unsafe.Pointer//go:noescapefunc ( unsafe.Pointer) ( unsafe.Pointer)//go:noescapefunc ( unsafe.Pointer) ( unsafe.Pointer)//go:noescapefunc ( unsafe.Pointer)//go:noescapefunc ( unsafe.Pointer) int// call calls fn with a copy of the n argument bytes pointed at by arg.// After fn returns, reflectcall copies n-retoffset result bytes// back into arg+retoffset before returning. If copying result bytes back,// the caller must pass the argument frame type as argtype, so that// call can execute appropriate write barriers during the copy.////go:linkname call runtime.reflectcallfunc ( *rtype, , unsafe.Pointer, uint32, uint32)func ( *rtype, interface{}, unsafe.Pointer)// memmove copies size bytes to dst from src. No write barriers are used.//go:noescapefunc (, unsafe.Pointer, uintptr)// typedmemmove copies a value of type t to dst from src.//go:noescapefunc ( *rtype, , unsafe.Pointer)// typedmemmovepartial is like typedmemmove but assumes that// dst and src point off bytes into the value and only copies size bytes.//go:noescapefunc ( *rtype, , unsafe.Pointer, , uintptr)// typedmemclr zeros the value at ptr of type t.//go:noescapefunc ( *rtype, unsafe.Pointer)// typedmemclrpartial is like typedmemclr but assumes that// dst points off bytes into the value and only clears size bytes.//go:noescapefunc ( *rtype, unsafe.Pointer, , uintptr)// typedslicecopy copies a slice of elemType values from src to dst,// returning the number of elements copied.//go:noescapefunc ( *rtype, , unsafeheader.Slice) int//go:noescapefunc ( *rtype, unsafe.Pointer, uintptr) uintptr// Dummy annotation marking that the value x escapes,// for use in cases where the reflect code is so clever that// the compiler cannot follow.func ( interface{}) {ifdummy.b {dummy.x = }}vardummystruct { b bool x interface{}}