Left: | ||
Right: |
LEFT | RIGHT |
---|---|
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 // The reflect package implements run-time reflection, allowing a program to | 5 // The reflect package implements run-time reflection, allowing a program to |
6 // manipulate objects with arbitrary types. The typical use is to take a | 6 // manipulate objects with arbitrary types. The typical use is to take a |
7 // value with static type interface{} and extract its dynamic type | 7 // value with static type interface{} and extract its dynamic type |
8 // information by calling Typeof, which returns a Type. | 8 // information by calling Typeof, which returns a Type. |
9 // | 9 // |
10 // A call to NewValue returns a Value representing the run-time data. | 10 // A call to NewValue returns a Value representing the run-time data. |
11 // MakeZero 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 package reflect | 13 package reflect |
14 | 14 |
15 import ( | 15 import ( |
16 "runtime" | 16 "runtime" |
17 "strconv" | 17 "strconv" |
18 "sync" | 18 "sync" |
19 "unsafe" | 19 "unsafe" |
20 ) | 20 ) |
21 | 21 |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
72 | 72 |
73 // Kind returns the specific kind of this type. | 73 // Kind returns the specific kind of this type. |
74 Kind() Kind | 74 Kind() Kind |
75 | 75 |
76 // Methods applicable only to some types, depending on Kind. | 76 // Methods applicable only to some types, depending on Kind. |
77 // The methods allowed for each kind are: | 77 // The methods allowed for each kind are: |
78 // | 78 // |
79 // Int*, Uint*, Float*, Complex*: Bits | 79 // Int*, Uint*, Float*, Complex*: Bits |
80 // Array: Elem, Len | 80 // Array: Elem, Len |
81 // Chan: ChanDir, Elem | 81 // Chan: ChanDir, Elem |
82 » //» Func: In, NumIn, Out, NumOut, DotDotDot. | 82 » //» Func: In, NumIn, Out, NumOut, IsVariadic. |
83 // Map: Key, Elem | 83 // Map: Key, Elem |
84 // Ptr: Elem | 84 // Ptr: Elem |
85 // Slice: Elem | 85 // Slice: Elem |
86 // Struct: Field, FieldByIndex, FieldByName, FieldByNameFunc, NumFi eld | 86 // Struct: Field, FieldByIndex, FieldByName, FieldByNameFunc, NumFi eld |
87 | 87 |
88 // Bits returns the size of the type in bits. | 88 // Bits returns the size of the type in bits. |
89 // It panics if the type's Kind is not one of the | 89 // It panics if the type's Kind is not one of the |
90 » // sized or unsized Int, Uint, Float, or Complex knids. | 90 » // sized or unsized Int, Uint, Float, or Complex kinds. |
r
2011/04/04 23:26:54
knids is a good word.
pointers are ok too, no?
| |
91 Bits() int | 91 Bits() int |
92 | 92 |
93 // ChanDir returns a channel type's direction. | 93 // ChanDir returns a channel type's direction. |
94 // It panics if the type's Kind is not Chan. | 94 // It panics if the type's Kind is not Chan. |
95 ChanDir() ChanDir | 95 ChanDir() ChanDir |
96 | 96 |
97 // IsVariadic returns true if a function type's final input parameter | 97 // IsVariadic returns true if a function type's final input parameter |
98 // is a "..." parameter. If so, t.In(t.NumIn() - 1) returns the paramet er's | 98 // is a "..." parameter. If so, t.In(t.NumIn() - 1) returns the paramet er's |
99 » // underlying static type []T. | 99 » // implicit actual type []T. |
r
2011/04/04 23:26:54
s/underlying static/implicit actual/ ?
avoid 'stat
| |
100 // | 100 // |
101 // For concreteness, if t represents func(x int, y ... float), then | 101 // For concreteness, if t represents func(x int, y ... float), then |
102 // | 102 // |
103 // t.NumIn() == 2 | 103 // t.NumIn() == 2 |
104 // t.In(0) is the reflect.Type for "int" | 104 // t.In(0) is the reflect.Type for "int" |
105 // t.In(1) is the reflect.Type for "[]float" | 105 // t.In(1) is the reflect.Type for "[]float" |
106 // t.IsVariadic() == true | 106 // t.IsVariadic() == true |
107 // | 107 // |
108 // IsVariadic panics if the type's Kind is not Func. | 108 // IsVariadic panics if the type's Kind is not Func. |
109 IsVariadic() bool | 109 IsVariadic() bool |
(...skipping 365 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
475 } | 475 } |
476 | 476 |
477 func (t *commonType) ChanDir() ChanDir { | 477 func (t *commonType) ChanDir() ChanDir { |
478 if t.Kind() != Chan { | 478 if t.Kind() != Chan { |
479 panic("reflect: ChanDir of non-chan type") | 479 panic("reflect: ChanDir of non-chan type") |
480 } | 480 } |
481 tt := (*chanType)(unsafe.Pointer(t)) | 481 tt := (*chanType)(unsafe.Pointer(t)) |
482 return ChanDir(tt.dir) | 482 return ChanDir(tt.dir) |
483 } | 483 } |
484 | 484 |
485 func (t *commonType) DotDotDot() bool { | 485 func (t *commonType) IsVariadic() bool { |
486 if t.Kind() != Func { | 486 if t.Kind() != Func { |
487 » » panic("reflect: DotDotDot of non-func type") | 487 » » panic("reflect: IsVariadic of non-func type") |
488 } | 488 } |
489 tt := (*funcType)(unsafe.Pointer(t)) | 489 tt := (*funcType)(unsafe.Pointer(t)) |
490 return tt.dotdotdot | 490 return tt.dotdotdot |
491 } | 491 } |
492 | 492 |
493 func (t *commonType) Elem() Type { | 493 func (t *commonType) Elem() Type { |
494 switch t.Kind() { | 494 switch t.Kind() { |
495 case Array: | 495 case Array: |
496 tt := (*arrayType)(unsafe.Pointer(t)) | 496 tt := (*arrayType)(unsafe.Pointer(t)) |
497 return toType(tt.elem) | 497 return toType(tt.elem) |
(...skipping 170 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
668 | 668 |
669 // TODO(gri): Should there be an error/bool indicator if the index | 669 // TODO(gri): Should there be an error/bool indicator if the index |
670 // is wrong for FieldByIndex? | 670 // is wrong for FieldByIndex? |
671 | 671 |
672 // FieldByIndex returns the nested field corresponding to index. | 672 // FieldByIndex returns the nested field corresponding to index. |
673 func (t *structType) FieldByIndex(index []int) (f StructField) { | 673 func (t *structType) FieldByIndex(index []int) (f StructField) { |
674 f.Type = Type(t.toType()) | 674 f.Type = Type(t.toType()) |
675 for i, x := range index { | 675 for i, x := range index { |
676 if i > 0 { | 676 if i > 0 { |
677 ft := f.Type | 677 ft := f.Type |
678 » » » if ft.Kind() == Ptr { | 678 » » » if ft.Kind() == Ptr && ft.Elem().Kind() == Struct { |
679 ft = ft.Elem() | 679 ft = ft.Elem() |
680 } | |
681 if ft.Kind() != Struct { | |
682 return StructField{} | |
683 } | 680 } |
684 f.Type = ft | 681 f.Type = ft |
685 } | 682 } |
686 f = f.Type.Field(x) | 683 f = f.Type.Field(x) |
687 } | 684 } |
688 return | 685 return |
689 } | 686 } |
690 | 687 |
691 const inf = 1 << 30 // infinity - no struct has that many nesting levels | 688 const inf = 1 << 30 // infinity - no struct has that many nesting levels |
692 | 689 |
(...skipping 165 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
858 p.hash = ct.hash*16777619 ^ '*' | 855 p.hash = ct.hash*16777619 ^ '*' |
859 | 856 |
860 p.uncommonType = nil | 857 p.uncommonType = nil |
861 p.ptrToThis = nil | 858 p.ptrToThis = nil |
862 p.elem = (*runtime.Type)(unsafe.Pointer(uintptr(unsafe.Pointer(ct)) - ui ntptr(unsafe.Offsetof(rt.ptrType)))) | 859 p.elem = (*runtime.Type)(unsafe.Pointer(uintptr(unsafe.Pointer(ct)) - ui ntptr(unsafe.Offsetof(rt.ptrType)))) |
863 | 860 |
864 ptrMap.m[ct] = p | 861 ptrMap.m[ct] = p |
865 ptrMap.Unlock() | 862 ptrMap.Unlock() |
866 return p.commonType.toType() | 863 return p.commonType.toType() |
867 } | 864 } |
LEFT | RIGHT |