OLD | NEW |
1 // Copyright 2009 The Go Authors. All rights reserved. | 1 // Copyright 2009 The Go Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style | 2 // Use of this source code is governed by a BSD-style |
3 // license that can be found in the LICENSE file. | 3 // license that can be found in the LICENSE file. |
4 | 4 |
5 // Package reflect implements run-time reflection, allowing a program to | 5 // Package reflect implements run-time reflection, allowing a program to |
6 // manipulate objects with arbitrary types. The typical use is to take a value | 6 // manipulate objects with arbitrary types. The typical use is to take a value |
7 // with static type interface{} and extract its dynamic type information by | 7 // with static type interface{} and extract its dynamic type information by |
8 // calling TypeOf, which returns a Type. | 8 // calling TypeOf, which returns a Type. |
9 // | 9 // |
10 // A call to ValueOf returns a Value representing the run-time data. | 10 // A call to ValueOf returns a Value representing the run-time data. |
11 // Zero takes a Type and returns a Value representing a zero value | 11 // Zero takes a Type and returns a Value representing a zero value |
12 // for that type. | 12 // for that type. |
13 // | 13 // |
14 // See "The Laws of Reflection" for an introduction to reflection in Go: | 14 // See "The Laws of Reflection" for an introduction to reflection in Go: |
15 // http://blog.golang.org/2011/09/laws-of-reflection.html | 15 // http://blog.golang.org/2011/09/laws-of-reflection.html |
16 package reflect | 16 package reflect |
17 | 17 |
18 import ( | 18 import ( |
19 "runtime" | |
20 "strconv" | 19 "strconv" |
21 "sync" | 20 "sync" |
22 "unsafe" | 21 "unsafe" |
23 ) | 22 ) |
24 | 23 |
25 // Type is the representation of a Go type. | 24 // Type is the representation of a Go type. |
26 // | 25 // |
27 // Not all methods apply to all kinds of types. Restrictions, | 26 // Not all methods apply to all kinds of types. Restrictions, |
28 // if any, are noted in the documentation for each method. | 27 // if any, are noted in the documentation for each method. |
29 // Use the Kind method to find out the kind of type before | 28 // Use the Kind method to find out the kind of type before |
(...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
174 | 173 |
175 // NumOut returns a function type's output parameter count. | 174 // NumOut returns a function type's output parameter count. |
176 // It panics if the type's Kind is not Func. | 175 // It panics if the type's Kind is not Func. |
177 NumOut() int | 176 NumOut() int |
178 | 177 |
179 // Out returns the type of a function type's i'th output parameter. | 178 // Out returns the type of a function type's i'th output parameter. |
180 // It panics if the type's Kind is not Func. | 179 // It panics if the type's Kind is not Func. |
181 // It panics if i is not in the range [0, NumOut()). | 180 // It panics if i is not in the range [0, NumOut()). |
182 Out(i int) Type | 181 Out(i int) Type |
183 | 182 |
184 » runtimeType() *runtime.Type | 183 » runtimeType() *runtimeType |
185 common() *commonType | 184 common() *commonType |
186 uncommon() *uncommonType | 185 uncommon() *uncommonType |
187 } | 186 } |
188 | 187 |
189 // A Kind represents the specific kind of type that a Type represents. | 188 // A Kind represents the specific kind of type that a Type represents. |
190 // The zero Kind is not a valid kind. | 189 // The zero Kind is not a valid kind. |
191 type Kind uint | 190 type Kind uint |
192 | 191 |
193 const ( | 192 const ( |
194 Invalid Kind = iota | 193 Invalid Kind = iota |
(...skipping 19 matching lines...) Expand all Loading... |
214 Interface | 213 Interface |
215 Map | 214 Map |
216 Ptr | 215 Ptr |
217 Slice | 216 Slice |
218 String | 217 String |
219 Struct | 218 Struct |
220 UnsafePointer | 219 UnsafePointer |
221 ) | 220 ) |
222 | 221 |
223 /* | 222 /* |
224 * Copy of data structures from ../runtime/type.go. | 223 * These data structures are known to the compiler (../../cmd/gc/reflect.c). |
225 * For comments, see the ones in that file. | 224 * A few are known to ../runtime/type.go to convey to debuggers. |
226 * | |
227 * These data structures are known to the compiler and the runtime. | |
228 * | |
229 * Putting these types in runtime instead of reflect means that | |
230 * reflect doesn't need to be autolinked into every binary, which | |
231 * simplifies bootstrapping and package dependencies. | |
232 * Unfortunately, it also means that reflect needs its own | |
233 * copy in order to access the private fields. | |
234 */ | 225 */ |
235 | 226 |
| 227 // The compiler can only construct empty interface values at |
| 228 // compile time; non-empty interface values get created |
| 229 // during initialization. Type is an empty interface |
| 230 // so that the compiler can lay out references as data. |
| 231 // The underlying type is *reflect.ArrayType and so on. |
| 232 type runtimeType interface{} |
| 233 |
236 // commonType is the common implementation of most values. | 234 // commonType is the common implementation of most values. |
237 // It is embedded in other, public struct types, but always | 235 // It is embedded in other, public struct types, but always |
238 // with a unique tag like `reflect:"array"` or `reflect:"ptr"` | 236 // with a unique tag like `reflect:"array"` or `reflect:"ptr"` |
239 // so that code cannot convert from, say, *arrayType to *ptrType. | 237 // so that code cannot convert from, say, *arrayType to *ptrType. |
240 | |
241 type commonType struct { | 238 type commonType struct { |
242 » size uintptr | 239 » size uintptr // size in bytes |
243 » hash uint32 | 240 » hash uint32 // hash of type; avoids computation in hash t
ables |
244 » _ uint8 | 241 » _ uint8 // unused/padding |
245 » align uint8 | 242 » align uint8 // alignment of variable with this type |
246 » fieldAlign uint8 | 243 » fieldAlign uint8 // alignment of struct field with this type |
247 » kind uint8 | 244 » kind uint8 // enumeration for C |
248 » alg *uintptr | 245 » alg *uintptr // algorithm table (../runtime/runtime.h:/Alg
) |
249 » string *string | 246 » string *string // string form; unnecessary but undeniably u
seful |
250 » *uncommonType | 247 » *uncommonType // (relatively) uncommon fields |
251 » ptrToThis *runtime.Type | 248 » ptrToThis *runtimeType // pointer to this type, if used in binary or
has methods |
252 } | 249 } |
253 | 250 |
| 251 // Method on non-interface type |
254 type method struct { | 252 type method struct { |
255 » name *string | 253 » name *string // name of method |
256 » pkgPath *string | 254 » pkgPath *string // nil for exported Names; otherwise import path |
257 » mtyp *runtime.Type | 255 » mtyp *runtimeType // method type (without receiver) |
258 » typ *runtime.Type | 256 » typ *runtimeType // .(*FuncType) underneath (with receiver) |
259 » ifn unsafe.Pointer | 257 » ifn unsafe.Pointer // fn used in interface call (one-word receiver) |
260 » tfn unsafe.Pointer | 258 » tfn unsafe.Pointer // fn used for normal method call |
261 } | 259 } |
262 | 260 |
| 261 // uncommonType is present only for types with names or methods |
| 262 // (if T is a named type, the uncommonTypes for T and *T have methods). |
| 263 // Using a pointer to this struct reduces the overall size required |
| 264 // to describe an unnamed type with no methods. |
263 type uncommonType struct { | 265 type uncommonType struct { |
264 » name *string | 266 » name *string // name of type |
265 » pkgPath *string | 267 » pkgPath *string // import path; nil for built-in types like int, string |
266 » methods []method | 268 » methods []method // methods associated with type |
267 } | 269 } |
268 | 270 |
269 // ChanDir represents a channel type's direction. | 271 // ChanDir represents a channel type's direction. |
270 type ChanDir int | 272 type ChanDir int |
271 | 273 |
272 const ( | 274 const ( |
273 » RecvDir ChanDir = 1 << iota | 275 » RecvDir ChanDir = 1 << iota // <-chan |
274 » SendDir | 276 » SendDir // chan<- |
275 » BothDir = RecvDir | SendDir | 277 » BothDir = RecvDir | SendDir // chan |
276 ) | 278 ) |
277 | 279 |
278 // arrayType represents a fixed array type. | 280 // arrayType represents a fixed array type. |
279 type arrayType struct { | 281 type arrayType struct { |
280 commonType `reflect:"array"` | 282 commonType `reflect:"array"` |
281 » elem *runtime.Type | 283 » elem *runtimeType // array element type |
282 » slice *runtime.Type | 284 » slice *runtimeType // slice type |
283 len uintptr | 285 len uintptr |
284 } | 286 } |
285 | 287 |
286 // chanType represents a channel type. | 288 // chanType represents a channel type. |
287 type chanType struct { | 289 type chanType struct { |
288 commonType `reflect:"chan"` | 290 commonType `reflect:"chan"` |
289 » elem *runtime.Type | 291 » elem *runtimeType // channel element type |
290 » dir uintptr | 292 » dir uintptr // channel direction (ChanDir) |
291 } | 293 } |
292 | 294 |
293 // funcType represents a function type. | 295 // funcType represents a function type. |
294 type funcType struct { | 296 type funcType struct { |
295 commonType `reflect:"func"` | 297 commonType `reflect:"func"` |
296 » dotdotdot bool | 298 » dotdotdot bool // last input parameter is ... |
297 » in []*runtime.Type | 299 » in []*runtimeType // input parameter types |
298 » out []*runtime.Type | 300 » out []*runtimeType // output parameter types |
299 } | 301 } |
300 | 302 |
301 // imethod represents a method on an interface type | 303 // imethod represents a method on an interface type |
302 type imethod struct { | 304 type imethod struct { |
303 » name *string | 305 » name *string // name of method |
304 » pkgPath *string | 306 » pkgPath *string // nil for exported Names; otherwise import path |
305 » typ *runtime.Type | 307 » typ *runtimeType // .(*FuncType) underneath |
306 } | 308 } |
307 | 309 |
308 // interfaceType represents an interface type. | 310 // interfaceType represents an interface type. |
309 type interfaceType struct { | 311 type interfaceType struct { |
310 commonType `reflect:"interface"` | 312 commonType `reflect:"interface"` |
311 » methods []imethod | 313 » methods []imethod // sorted by hash |
312 } | 314 } |
313 | 315 |
314 // mapType represents a map type. | 316 // mapType represents a map type. |
315 type mapType struct { | 317 type mapType struct { |
316 commonType `reflect:"map"` | 318 commonType `reflect:"map"` |
317 » key *runtime.Type | 319 » key *runtimeType // map key type |
318 » elem *runtime.Type | 320 » elem *runtimeType // map element (value) type |
319 } | 321 } |
320 | 322 |
321 // ptrType represents a pointer type. | 323 // ptrType represents a pointer type. |
322 type ptrType struct { | 324 type ptrType struct { |
323 commonType `reflect:"ptr"` | 325 commonType `reflect:"ptr"` |
324 » elem *runtime.Type | 326 » elem *runtimeType // pointer element (pointed at) type |
325 } | 327 } |
326 | 328 |
327 // sliceType represents a slice type. | 329 // sliceType represents a slice type. |
328 type sliceType struct { | 330 type sliceType struct { |
329 commonType `reflect:"slice"` | 331 commonType `reflect:"slice"` |
330 » elem *runtime.Type | 332 » elem *runtimeType // slice element type |
331 } | 333 } |
332 | 334 |
333 // Struct field | 335 // Struct field |
334 type structField struct { | 336 type structField struct { |
335 » name *string | 337 » name *string // nil for embedded fields |
336 » pkgPath *string | 338 » pkgPath *string // nil for exported Names; otherwise import path |
337 » typ *runtime.Type | 339 » typ *runtimeType // type of field |
338 » tag *string | 340 » tag *string // nil if no tag |
339 » offset uintptr | 341 » offset uintptr // byte offset of field within struct |
340 } | 342 } |
341 | 343 |
342 // structType represents a struct type. | 344 // structType represents a struct type. |
343 type structType struct { | 345 type structType struct { |
344 commonType `reflect:"struct"` | 346 commonType `reflect:"struct"` |
345 » fields []structField | 347 » fields []structField // sorted by offset |
346 } | 348 } |
347 | 349 |
348 /* | 350 /* |
349 * The compiler knows the exact layout of all the data structures above. | 351 * The compiler knows the exact layout of all the data structures above. |
350 * The compiler does not know about the data structures and methods below. | 352 * The compiler does not know about the data structures and methods below. |
351 */ | 353 */ |
352 | 354 |
353 // Method represents a single method. | 355 // Method represents a single method. |
354 type Method struct { | 356 type Method struct { |
355 PkgPath string // empty for uppercase Name | 357 PkgPath string // empty for uppercase Name |
(...skipping 546 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
902 // match function and a boolean to indicate if the field was found. | 904 // match function and a boolean to indicate if the field was found. |
903 func (t *structType) FieldByNameFunc(match func(string) bool) (f StructField, pr
esent bool) { | 905 func (t *structType) FieldByNameFunc(match func(string) bool) (f StructField, pr
esent bool) { |
904 if ff, fd := t.fieldByNameFunc(match, make(map[*structType]bool), 0); fd
< inf { | 906 if ff, fd := t.fieldByNameFunc(match, make(map[*structType]bool), 0); fd
< inf { |
905 ff.Index = ff.Index[0 : fd+1] | 907 ff.Index = ff.Index[0 : fd+1] |
906 f, present = ff, true | 908 f, present = ff, true |
907 } | 909 } |
908 return | 910 return |
909 } | 911 } |
910 | 912 |
911 // Convert runtime type to reflect type. | 913 // Convert runtime type to reflect type. |
912 func toCommonType(p *runtime.Type) *commonType { | 914 func toCommonType(p *runtimeType) *commonType { |
913 if p == nil { | 915 if p == nil { |
914 return nil | 916 return nil |
915 } | 917 } |
916 » type hdr struct { | 918 » return (*p).(*commonType) |
917 » » x interface{} | |
918 » » t commonType | |
919 » } | |
920 » x := unsafe.Pointer(p) | |
921 » return &(*hdr)(x).t | |
922 } | 919 } |
923 | 920 |
924 func toType(p *runtime.Type) Type { | 921 func toType(p *runtimeType) Type { |
925 if p == nil { | 922 if p == nil { |
926 return nil | 923 return nil |
927 } | 924 } |
928 » return toCommonType(p).toType() | 925 » return (*p).(*commonType) |
929 } | 926 } |
930 | 927 |
931 // TypeOf returns the reflection Type of the value in the interface{}. | 928 // TypeOf returns the reflection Type of the value in the interface{}. |
932 func TypeOf(i interface{}) Type { | 929 func TypeOf(i interface{}) Type { |
933 eface := *(*emptyInterface)(unsafe.Pointer(&i)) | 930 eface := *(*emptyInterface)(unsafe.Pointer(&i)) |
934 return toType(eface.typ) | 931 return toType(eface.typ) |
935 } | 932 } |
936 | 933 |
937 // ptrMap is the cache for PtrTo. | 934 // ptrMap is the cache for PtrTo. |
938 var ptrMap struct { | 935 var ptrMap struct { |
939 sync.RWMutex | 936 sync.RWMutex |
940 m map[*commonType]*ptrType | 937 m map[*commonType]*ptrType |
941 } | 938 } |
942 | 939 |
943 func (t *commonType) runtimeType() *runtime.Type { | 940 func (t *commonType) runtimeType() *runtimeType { |
944 » // The runtime.Type always precedes the commonType in memory. | 941 » // The runtimeType always precedes the commonType in memory. |
945 // Adjust pointer to find it. | 942 // Adjust pointer to find it. |
946 var rt struct { | 943 var rt struct { |
947 » » i runtime.Type | 944 » » i runtimeType |
948 ct commonType | 945 ct commonType |
949 } | 946 } |
950 » return (*runtime.Type)(unsafe.Pointer(uintptr(unsafe.Pointer(t)) - unsaf
e.Offsetof(rt.ct))) | 947 » return (*runtimeType)(unsafe.Pointer(uintptr(unsafe.Pointer(t)) - unsafe
.Offsetof(rt.ct))) |
951 } | 948 } |
952 | 949 |
953 // PtrTo returns the pointer type with element t. | 950 // PtrTo returns the pointer type with element t. |
954 // For example, if t represents type Foo, PtrTo(t) represents *Foo. | 951 // For example, if t represents type Foo, PtrTo(t) represents *Foo. |
955 func PtrTo(t Type) Type { | 952 func PtrTo(t Type) Type { |
956 return t.(*commonType).ptrTo() | 953 return t.(*commonType).ptrTo() |
957 } | 954 } |
958 | 955 |
959 func (ct *commonType) ptrTo() *commonType { | 956 func (ct *commonType) ptrTo() *commonType { |
960 if p := ct.ptrToThis; p != nil { | 957 if p := ct.ptrToThis; p != nil { |
(...skipping 18 matching lines...) Expand all Loading... |
979 ptrMap.m = make(map[*commonType]*ptrType) | 976 ptrMap.m = make(map[*commonType]*ptrType) |
980 } | 977 } |
981 p := ptrMap.m[ct] | 978 p := ptrMap.m[ct] |
982 if p != nil { | 979 if p != nil { |
983 // some other goroutine won the race and created it | 980 // some other goroutine won the race and created it |
984 ptrMap.Unlock() | 981 ptrMap.Unlock() |
985 return &p.commonType | 982 return &p.commonType |
986 } | 983 } |
987 | 984 |
988 var rt struct { | 985 var rt struct { |
989 » » i runtime.Type | 986 » » i runtimeType |
990 ptrType | 987 ptrType |
991 } | 988 } |
992 » rt.i = (*runtime.PtrType)(unsafe.Pointer(&rt.ptrType)) | 989 » rt.i = &rt.commonType |
993 | 990 |
994 // initialize p using *byte's ptrType as a prototype. | 991 // initialize p using *byte's ptrType as a prototype. |
995 // have to do assignment as ptrType, not runtime.PtrType, | |
996 // in order to write to unexported fields. | |
997 p = &rt.ptrType | 992 p = &rt.ptrType |
998 » bp := (*ptrType)(unsafe.Pointer(unsafe.Typeof((*byte)(nil)).(*runtime.Pt
rType))) | 993 » var ibyte interface{} = (*byte)(nil) |
| 994 » bp := (*ptrType)(unsafe.Pointer((**(**runtimeType)(unsafe.Pointer(&ibyte
))).(*commonType))) |
999 *p = *bp | 995 *p = *bp |
1000 | 996 |
1001 s := "*" + *ct.string | 997 s := "*" + *ct.string |
1002 p.string = &s | 998 p.string = &s |
1003 | 999 |
1004 // For the type structures linked into the binary, the | 1000 // For the type structures linked into the binary, the |
1005 // compiler provides a good hash of the string. | 1001 // compiler provides a good hash of the string. |
1006 // Create a good hash for the new string by using | 1002 // Create a good hash for the new string by using |
1007 // the FNV-1 hash's mixing function to combine the | 1003 // the FNV-1 hash's mixing function to combine the |
1008 // old hash and the new "*". | 1004 // old hash and the new "*". |
1009 p.hash = ct.hash*16777619 ^ '*' | 1005 p.hash = ct.hash*16777619 ^ '*' |
1010 | 1006 |
1011 p.uncommonType = nil | 1007 p.uncommonType = nil |
1012 p.ptrToThis = nil | 1008 p.ptrToThis = nil |
1013 » p.elem = (*runtime.Type)(unsafe.Pointer(uintptr(unsafe.Pointer(ct)) - un
safe.Offsetof(rt.ptrType))) | 1009 » p.elem = (*runtimeType)(unsafe.Pointer(uintptr(unsafe.Pointer(ct)) - uns
afe.Offsetof(rt.ptrType))) |
1014 | 1010 |
1015 ptrMap.m[ct] = p | 1011 ptrMap.m[ct] = p |
1016 ptrMap.Unlock() | 1012 ptrMap.Unlock() |
1017 return &p.commonType | 1013 return &p.commonType |
1018 } | 1014 } |
1019 | 1015 |
1020 func (t *commonType) Implements(u Type) bool { | 1016 func (t *commonType) Implements(u Type) bool { |
1021 if u == nil { | 1017 if u == nil { |
1022 panic("reflect: nil type passed to Type.Implements") | 1018 panic("reflect: nil type passed to Type.Implements") |
1023 } | 1019 } |
(...skipping 146 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1170 if tf.name != vf.name || tf.pkgPath != vf.pkgPath || | 1166 if tf.name != vf.name || tf.pkgPath != vf.pkgPath || |
1171 tf.typ != vf.typ || tf.tag != vf.tag || tf.offse
t != vf.offset { | 1167 tf.typ != vf.typ || tf.tag != vf.tag || tf.offse
t != vf.offset { |
1172 return false | 1168 return false |
1173 } | 1169 } |
1174 } | 1170 } |
1175 return true | 1171 return true |
1176 } | 1172 } |
1177 | 1173 |
1178 return false | 1174 return false |
1179 } | 1175 } |
OLD | NEW |