diff options
author | Rob Pike <r@golang.org> | 2009-03-09 17:47:15 -0700 |
---|---|---|
committer | Rob Pike <r@golang.org> | 2009-03-09 17:47:15 -0700 |
commit | ae8420b87f4a4c0d98646c90fac781f88f89c03a (patch) | |
tree | 773482467f0848b97320f42a7c58666977d9c110 /src | |
parent | 93bef1871e1fe972b0547acefbc723f518f8979f (diff) | |
download | golang-ae8420b87f4a4c0d98646c90fac781f88f89c03a.tar.gz |
document reflect.
R=rsc
DELTA=201 (90 added, 0 deleted, 111 changed)
OCL=25904
CL=25966
Diffstat (limited to 'src')
-rw-r--r-- | src/lib/reflect/all_test.go | 22 | ||||
-rw-r--r-- | src/lib/reflect/tostring.go | 54 | ||||
-rw-r--r-- | src/lib/reflect/type.go | 71 | ||||
-rw-r--r-- | src/lib/reflect/value.go | 147 |
4 files changed, 192 insertions, 102 deletions
diff --git a/src/lib/reflect/all_test.go b/src/lib/reflect/all_test.go index f6428fdf3..7636f0950 100644 --- a/src/lib/reflect/all_test.go +++ b/src/lib/reflect/all_test.go @@ -43,7 +43,7 @@ func assert(s, t string) { func typedump(s, t string) { typ := reflect.ParseTypeString("", s); - assert(reflect.TypeToString(typ, true), t); + assert(reflect.typeToString(typ, true), t); } func valuedump(s, t string) { @@ -84,7 +84,7 @@ func valuedump(s, t string) { case reflect.BoolKind: v.(reflect.BoolValue).Set(true); } - assert(reflect.ValueToString(v), t); + assert(reflect.valueToString(v), t); } type T struct { a int; b float64; c string; d *int } @@ -156,43 +156,43 @@ func TestAll(tt *testing.T) { // TODO(r): wrap up better { var tmp = 123; value := reflect.NewValue(tmp); - assert(reflect.ValueToString(value), "123"); + assert(reflect.valueToString(value), "123"); } { var tmp = 123.4; value := reflect.NewValue(tmp); - assert(reflect.ValueToString(value), "123.4"); + assert(reflect.valueToString(value), "123.4"); } { var tmp = "abc"; value := reflect.NewValue(tmp); - assert(reflect.ValueToString(value), "abc"); + assert(reflect.valueToString(value), "abc"); } { var i int = 7; var tmp = &T{123, 456.75, "hello", &i}; value := reflect.NewValue(tmp); - assert(reflect.ValueToString(value.(reflect.PtrValue).Sub()), "reflect.T{123, 456.75, hello, *int(@)}"); + assert(reflect.valueToString(value.(reflect.PtrValue).Sub()), "reflect.T{123, 456.75, hello, *int(@)}"); } { type C chan *T; // TODO: should not be necessary var tmp = new(C); value := reflect.NewValue(tmp); - assert(reflect.ValueToString(value), "*reflect.C·all_test(@)"); + assert(reflect.valueToString(value), "*reflect.C·all_test(@)"); } // { // type A [10]int; // var tmp A = A{1,2,3,4,5,6,7,8,9,10}; // value := reflect.NewValue(&tmp); -// assert(reflect.ValueToString(value.(reflect.PtrValue).Sub()), "reflect.A·all_test{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}"); +// assert(reflect.valueToString(value.(reflect.PtrValue).Sub()), "reflect.A·all_test{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}"); // value.(reflect.PtrValue).Sub().(reflect.ArrayValue).Elem(4).(reflect.IntValue).Set(123); -// assert(reflect.ValueToString(value.(reflect.PtrValue).Sub()), "reflect.A·all_test{1, 2, 3, 4, 123, 6, 7, 8, 9, 10}"); +// assert(reflect.valueToString(value.(reflect.PtrValue).Sub()), "reflect.A·all_test{1, 2, 3, 4, 123, 6, 7, 8, 9, 10}"); // } { type AA []int; var tmp = AA{1,2,3,4,5,6,7,8,9,10}; value := reflect.NewValue(&tmp); // TODO: NewValue(tmp) too - assert(reflect.ValueToString(value.(reflect.PtrValue).Sub()), "reflect.AA·all_test{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}"); + assert(reflect.valueToString(value.(reflect.PtrValue).Sub()), "reflect.AA·all_test{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}"); value.(reflect.PtrValue).Sub().(reflect.ArrayValue).Elem(4).(reflect.IntValue).Set(123); - assert(reflect.ValueToString(value.(reflect.PtrValue).Sub()), "reflect.AA·all_test{1, 2, 3, 4, 123, 6, 7, 8, 9, 10}"); + assert(reflect.valueToString(value.(reflect.PtrValue).Sub()), "reflect.AA·all_test{1, 2, 3, 4, 123, 6, 7, 8, 9, 10}"); } { diff --git a/src/lib/reflect/tostring.go b/src/lib/reflect/tostring.go index b2ccfdf48..202d0ecbc 100644 --- a/src/lib/reflect/tostring.go +++ b/src/lib/reflect/tostring.go @@ -3,7 +3,9 @@ // license that can be found in the LICENSE file. // Reflection library. -// Formatting of types and values for debugging. +// Formatting of reflection types and values for debugging. +// Not defined as methods so they do not need to be linked into most binaries; +// the functions are not used by the library itself, only in tests. package reflect @@ -12,8 +14,8 @@ import ( "strconv"; ) -func TypeToString(typ Type, expand bool) string -func ValueToString(val Value) string +func typeToString(typ Type, expand bool) string +func valueToString(val Value) string func doubleQuote(s string) string { out := "\""; @@ -50,7 +52,7 @@ func typeFieldsToString(t hasFields, sep string) string { if str1 != "" { str1 += " " } - str1 += TypeToString(typ, false); + str1 += typeToString(typ, false); if tag != "" { str1 += " " + doubleQuote(tag); } @@ -62,7 +64,11 @@ func typeFieldsToString(t hasFields, sep string) string { return str; } -func TypeToString(typ Type, expand bool) string { +// typeToString returns a textual representation of typ. The expand +// flag specifies whether to expand the contents of type names; if false, +// the name itself is used as the representation. +// Meant for debugging only; typ.String() serves for most purposes. +func typeToString(typ Type, expand bool) string { var str string; if name := typ.Name(); !expand && name != "" { return name @@ -78,7 +84,7 @@ func TypeToString(typ Type, expand bool) string { return typ.Name(); case PtrKind: p := typ.(PtrType); - return "*" + TypeToString(p.Sub(), false); + return "*" + typeToString(p.Sub(), false); case ArrayKind: a := typ.(ArrayType); if a.IsSlice() { @@ -86,11 +92,11 @@ func TypeToString(typ Type, expand bool) string { } else { str = "[" + strconv.Itoa64(int64(a.Len())) + "]" } - return str + TypeToString(a.Elem(), false); + return str + typeToString(a.Elem(), false); case MapKind: m := typ.(MapType); - str = "map[" + TypeToString(m.Key(), false) + "]"; - return str + TypeToString(m.Elem(), false); + str = "map[" + typeToString(m.Key(), false) + "]"; + return str + typeToString(m.Elem(), false); case ChanKind: c := typ.(ChanType); switch c.Dir() { @@ -101,9 +107,9 @@ func TypeToString(typ Type, expand bool) string { case BothDir: str = "chan"; default: - panicln("reflect.TypeToString: unknown chan direction"); + panicln("reflect.typeToString: unknown chan direction"); } - return str + TypeToString(c.Elem(), false); + return str + typeToString(c.Elem(), false); case StructKind: return "struct{" + typeFieldsToString(typ.(StructType), ";") + "}"; case InterfaceKind: @@ -116,9 +122,9 @@ func TypeToString(typ Type, expand bool) string { } return str; default: - panicln("reflect.TypeToString: can't print type ", typ.Kind()); + panicln("reflect.typeToString: can't print type ", typ.Kind()); } - return "reflect.TypeToString: can't happen"; + return "reflect.typeToString: can't happen"; } // TODO: want an unsigned one too @@ -126,7 +132,9 @@ func integer(v int64) string { return strconv.Itoa64(v); } -func ValueToString(val Value) string { +// valueToString returns a textual representation of the reflection value val. +// For debugging only. +func valueToString(val Value) string { var str string; typ := val.Type(); switch(val.Kind()) { @@ -174,41 +182,41 @@ func ValueToString(val Value) string { } case PtrKind: v := val.(PtrValue); - return TypeToString(typ, false) + "(" + integer(int64(uintptr(v.Get()))) + ")"; + return typeToString(typ, false) + "(" + integer(int64(uintptr(v.Get()))) + ")"; case ArrayKind: t := typ.(ArrayType); v := val.(ArrayValue); - str += TypeToString(t, false); + str += typeToString(t, false); str += "{"; for i := 0; i < v.Len(); i++ { if i > 0 { str += ", " } - str += ValueToString(v.Elem(i)); + str += valueToString(v.Elem(i)); } str += "}"; return str; case MapKind: t := typ.(MapType); v := val.(MapValue); - str = TypeToString(t, false); + str = typeToString(t, false); str += "{"; str += "<can't iterate on maps>"; str += "}"; return str; case ChanKind: - str = TypeToString(typ, false); + str = typeToString(typ, false); return str; case StructKind: t := typ.(StructType); v := val.(StructValue); - str += TypeToString(t, false); + str += typeToString(t, false); str += "{"; for i := 0; i < v.Len(); i++ { if i > 0 { str += ", " } - str += ValueToString(v.Field(i)); + str += valueToString(v.Field(i)); } str += "}"; return str; @@ -217,7 +225,7 @@ func ValueToString(val Value) string { case FuncKind: return "can't print funcs yet"; default: - panicln("reflect.ValueToString: can't print type ", val.Kind()); + panicln("reflect.valueToString: can't print type ", val.Kind()); } - return "reflect.ValueToString: can't happen"; + return "reflect.valueToString: can't happen"; } diff --git a/src/lib/reflect/type.go b/src/lib/reflect/type.go index 96953f3b0..fcc33e442 100644 --- a/src/lib/reflect/type.go +++ b/src/lib/reflect/type.go @@ -5,6 +5,10 @@ // Reflection library. // Types and parsing of type strings. +// This package implements data ``reflection''. A program can use it to analyze types +// and values it does not know at compile time, such as the values passed in a call +// to a function with a ... parameter. This is achieved by extracting the dynamic +// contents of an interface value. package reflect import ( @@ -19,6 +23,7 @@ func ExpandType(name string) Type func typestrings() string // implemented in C; declared here +// These constants identify what kind of thing a Type represents: an int, struct, etc. const ( MissingKind = iota; ArrayKind; @@ -57,10 +62,18 @@ const ( var missingString = "$missing$" // syntactic name for undefined type names var dotDotDotString = "..." +// Type is the generic interface to reflection types. Once its Kind is known, +// such as BoolKind, the Type can be narrowed to the appropriate, more +// specific interface, such as BoolType. Such narrowed types still implement +// the Type interface. type Type interface { + // The kind of thing described: ArrayKind, BoolKind, etc. Kind() int; + // The name declared for the type ("int", "BoolArray", etc.). Name() string; + // For a named type, same as Name(); otherwise a representation of the type such as "[]int". String() string; + // The number of bytes needed to store a value; analogous to unsafe.Sizeof(). Size() int; } @@ -104,7 +117,10 @@ func newBasicType(name string, kind int, size int) Type { return &basicType{ commonType{kind, name, name, size} } } -// Prebuilt basic types +// Prebuilt basic Type objects representing the predeclared basic types. +// Most are self-evident except: +// Missing represents types whose representation cannot be discovered; usually an error. +// DotDotDot represents the pseudo-type of a ... parameter. var ( Missing = newBasicType(missingString, MissingKind, 1); empty interface{}; @@ -149,9 +165,10 @@ func (t *stubType) Get() Type { // -- Pointer +// PtrType represents a pointer. type PtrType interface { Type; - Sub() Type + Sub() Type // The type of the pointed-to item; for "*int", it will be "int". } type ptrTypeStruct struct { @@ -169,11 +186,12 @@ func (t *ptrTypeStruct) Sub() Type { // -- Array +// ArrayType represents an array or slice type. type ArrayType interface { Type; - IsSlice() bool; - Len() int; - Elem() Type; + IsSlice() bool; // True for slices, false for arrays. + Len() int; // 0 for slices, the length for array types. + Elem() Type; // The type of the elements. } type arrayTypeStruct struct { @@ -184,7 +202,7 @@ type arrayTypeStruct struct { } func newArrayTypeStruct(name, typestring string, open bool, len int, elem *stubType) *arrayTypeStruct { - return &arrayTypeStruct{ commonType{ArrayKind, typestring, name, 0}, elem, open, len} + return &arrayTypeStruct{ commonType{ArrayKind, typestring, name, 0 }, elem, open, len} } func (t *arrayTypeStruct) Size() int { @@ -199,7 +217,9 @@ func (t *arrayTypeStruct) IsSlice() bool { } func (t *arrayTypeStruct) Len() int { - // what about open array? TODO + if t.isslice { + return 0 + } return t.len } @@ -209,10 +229,11 @@ func (t *arrayTypeStruct) Elem() Type { // -- Map +// MapType represents a map type. type MapType interface { Type; - Key() Type; - Elem() Type; + Key() Type; // The type of the keys. + Elem() Type; // The type of the elements/values. } type mapTypeStruct struct { @@ -235,13 +256,15 @@ func (t *mapTypeStruct) Elem() Type { // -- Chan +// ChanType represents a chan type. type ChanType interface { Type; - Dir() int; - Elem() Type; + Dir() int; // The direction of the channel. + Elem() Type; // The type of the elements. } -const ( // channel direction +// Channel direction. +const ( SendDir = 1 << iota; RecvDir; BothDir = SendDir | RecvDir; @@ -267,9 +290,13 @@ func (t *chanTypeStruct) Elem() Type { // -- Struct +// StructType represents a struct type. type StructType interface { Type; - Field(int) (name string, typ Type, tag string, offset int); + // Field returns, for field i, its name, Type, tag information, and byte offset. + // The indices are in declaration order starting at 0. + Field(i int) (name string, typ Type, tag string, offset int); + // Len is the number of fields. Len() int; } @@ -328,8 +355,12 @@ func (t *structTypeStruct) Len() int { // -- Interface +// InterfaceType represents an interface type. +// It behaves much like a StructType, treating the methods as fields. type InterfaceType interface { Type; + // Field returns, for method i, its name, Type, the empty string, and 0. + // The indices are in declaration order starting at 0. TODO: is this true? Field(int) (name string, typ Type, tag string, offset int); Len() int; } @@ -355,10 +386,11 @@ var nilInterface = newInterfaceTypeStruct("nil", "", make([]structField, 0)); // -- Func +// FuncType represents a function type. type FuncType interface { Type; - In() StructType; - Out() StructType; + In() StructType; // The parameters in the form of a StructType. + Out() StructType; // The results in the form of a StructType. } type funcTypeStruct struct { @@ -466,6 +498,9 @@ func init() { } /* + Parsing of type strings. These strings are how the run-time recovers type + information dynamically. + Grammar stubtype = - represent as StubType when possible @@ -850,6 +885,9 @@ func (p *typeParser) Type(name string) *stubType { return s; } +// ParseTypeString takes a type name and type string (such as "[]int") and +// returns the Type structure representing a type name specifying the corresponding +// type. An empty typestring represents (the type of) a nil interface value. func ParseTypeString(name, typestring string) Type { if typestring == "" { // If the typestring is empty, it represents (the type of) a nil interface value @@ -909,7 +947,8 @@ func typeNameToTypeString(name string) string { return s } -// Type is known by name. Find (and create if necessary) its real type. +// ExpandType takes the name of a type and returns its Type structure, +// unpacking the associated type string if necessary. func ExpandType(name string) Type { lock(); t, ok := types[name]; diff --git a/src/lib/reflect/value.go b/src/lib/reflect/value.go index 9056d74d5..f4e63407a 100644 --- a/src/lib/reflect/value.go +++ b/src/lib/reflect/value.go @@ -12,16 +12,25 @@ import ( "unsafe"; ) +// Addr is shorthand for unsafe.Pointer and is used to represent the address of Values. type Addr unsafe.Pointer func equalType(a, b Type) bool { return a.String() == b.String() } +// Value is the generic interface to reflection values. Once its Kind is known, +// such as BoolKind, the Value can be narrowed to the appropriate, more +// specific interface, such as BoolValue. Such narrowed values still implement +// the Value interface. type Value interface { + // The kind of thing described: ArrayKind, BoolKind, etc. Kind() int; + // The reflection Type of the value. Type() Type; + // The address of the value. Addr() Addr; + // The value itself is the dynamic value of an empty interface. Interface() interface {}; } @@ -65,6 +74,8 @@ type creatorFn func(typ Type, addr Addr) Value // -- Missing +// MissingValue represents a value whose type is not known. It usually +// indicates an error. type MissingValue interface { Value; } @@ -79,10 +90,11 @@ func missingCreator(typ Type, addr Addr) Value { // -- Int +// IntValue represents an int value. type IntValue interface { Value; - Get() int; - Set(int); + Get() int; // Get the underlying int. + Set(int); // Set the underlying int. } type intValueStruct struct { @@ -103,10 +115,11 @@ func (v *intValueStruct) Set(i int) { // -- Int8 +// Int8Value represents an int8 value. type Int8Value interface { Value; - Get() int8; - Set(int8); + Get() int8; // Get the underlying int8. + Set(int8); // Set the underlying int8. } type int8ValueStruct struct { @@ -127,10 +140,11 @@ func (v *int8ValueStruct) Set(i int8) { // -- Int16 +// Int16Value represents an int16 value. type Int16Value interface { Value; - Get() int16; - Set(int16); + Get() int16; // Get the underlying int16. + Set(int16); // Set the underlying int16. } type int16ValueStruct struct { @@ -151,10 +165,11 @@ func (v *int16ValueStruct) Set(i int16) { // -- Int32 +// Int32Value represents an int32 value. type Int32Value interface { Value; - Get() int32; - Set(int32); + Get() int32; // Get the underlying int32. + Set(int32); // Set the underlying int32. } type int32ValueStruct struct { @@ -175,10 +190,11 @@ func (v *int32ValueStruct) Set(i int32) { // -- Int64 +// Int64Value represents an int64 value. type Int64Value interface { Value; - Get() int64; - Set(int64); + Get() int64; // Get the underlying int64. + Set(int64); // Set the underlying int64. } type int64ValueStruct struct { @@ -199,10 +215,11 @@ func (v *int64ValueStruct) Set(i int64) { // -- Uint +// UintValue represents a uint value. type UintValue interface { Value; - Get() uint; - Set(uint); + Get() uint; // Get the underlying uint. + Set(uint); // Set the underlying uint. } type uintValueStruct struct { @@ -223,10 +240,11 @@ func (v *uintValueStruct) Set(i uint) { // -- Uint8 +// Uint8Value represents a uint8 value. type Uint8Value interface { Value; - Get() uint8; - Set(uint8); + Get() uint8; // Get the underlying uint8. + Set(uint8); // Set the underlying uint8. } type uint8ValueStruct struct { @@ -247,10 +265,11 @@ func (v *uint8ValueStruct) Set(i uint8) { // -- Uint16 +// Uint16Value represents a uint16 value. type Uint16Value interface { Value; - Get() uint16; - Set(uint16); + Get() uint16; // Get the underlying uint16. + Set(uint16); // Set the underlying uint16. } type uint16ValueStruct struct { @@ -271,10 +290,11 @@ func (v *uint16ValueStruct) Set(i uint16) { // -- Uint32 +// Uint32Value represents a uint32 value. type Uint32Value interface { Value; - Get() uint32; - Set(uint32); + Get() uint32; // Get the underlying uint32. + Set(uint32); // Set the underlying uint32. } type uint32ValueStruct struct { @@ -295,10 +315,11 @@ func (v *uint32ValueStruct) Set(i uint32) { // -- Uint64 +// Uint64Value represents a uint64 value. type Uint64Value interface { Value; - Get() uint64; - Set(uint64); + Get() uint64; // Get the underlying uint64. + Set(uint64); // Set the underlying uint64. } type uint64ValueStruct struct { @@ -319,10 +340,11 @@ func (v *uint64ValueStruct) Set(i uint64) { // -- Uintptr +// UintptrValue represents a uintptr value. type UintptrValue interface { Value; - Get() uintptr; - Set(uintptr); + Get() uintptr; // Get the underlying uintptr. + Set(uintptr); // Set the underlying uintptr. } type uintptrValueStruct struct { @@ -343,10 +365,11 @@ func (v *uintptrValueStruct) Set(i uintptr) { // -- Float +// FloatValue represents a float value. type FloatValue interface { Value; - Get() float; - Set(float); + Get() float; // Get the underlying float. + Set(float); // Get the underlying float. } type floatValueStruct struct { @@ -367,10 +390,11 @@ func (v *floatValueStruct) Set(f float) { // -- Float32 +// Float32Value represents a float32 value. type Float32Value interface { Value; - Get() float32; - Set(float32); + Get() float32; // Get the underlying float32. + Set(float32); // Get the underlying float32. } type float32ValueStruct struct { @@ -391,10 +415,11 @@ func (v *float32ValueStruct) Set(f float32) { // -- Float64 +// Float64Value represents a float64 value. type Float64Value interface { Value; - Get() float64; - Set(float64); + Get() float64; // Get the underlying float64. + Set(float64); // Get the underlying float64. } type float64ValueStruct struct { @@ -415,10 +440,11 @@ func (v *float64ValueStruct) Set(f float64) { // -- Float80 +// Float80Value represents a float80 value. type Float80Value interface { Value; - Get() float80; - Set(float80); + Get() float80; // Get the underlying float80. + Set(float80); // Get the underlying float80. } type float80ValueStruct struct { @@ -442,10 +468,11 @@ func (v *Float80ValueStruct) Set(f float80) { // -- String +// StringValue represents a string value. type StringValue interface { Value; - Get() string; - Set(string); + Get() string; // Get the underlying string value. + Set(string); // Set the underlying string value. } type stringValueStruct struct { @@ -466,10 +493,11 @@ func (v *stringValueStruct) Set(s string) { // -- Bool +// BoolValue represents a bool value. type BoolValue interface { Value; - Get() bool; - Set(bool); + Get() bool; // Get the underlying bool value. + Set(bool); // Set the underlying bool value. } type boolValueStruct struct { @@ -490,11 +518,12 @@ func (v *boolValueStruct) Set(b bool) { // -- Pointer +// PtrValue represents a pointer value. type PtrValue interface { Value; - Sub() Value; - Get() Addr; - SetSub(Value); + Sub() Value; // The Value pointed to. + Get() Addr; // Get the address stored in the pointer. + SetSub(Value); // Set the the pointed-to Value. } type ptrValueStruct struct { @@ -526,15 +555,16 @@ func ptrCreator(typ Type, addr Addr) Value { // -- Array // Slices and arrays are represented by the same interface. +// ArrayValue represents an array or slice value. type ArrayValue interface { Value; - IsSlice() bool; - Len() int; - Cap() int; - Elem(i int) Value; - SetLen(len int); - Set(src ArrayValue); - CopyFrom(src ArrayValue, n int) + IsSlice() bool; // Is this a slice (true) or array (false)? + Len() int; // The length of the array/slice. + Cap() int; // The capacity of the array/slice (==Len() for arrays). + Elem(i int) Value; // The Value of the i'th element. + SetLen(len int); // Set the length; slice only. + Set(src ArrayValue); // Set the underlying Value; slice only for src and dest both. + CopyFrom(src ArrayValue, n int) // Copy the elements from src; lengths must match. } func copyArray(dst ArrayValue, src ArrayValue, n int); @@ -581,7 +611,7 @@ func (v *sliceValueStruct) SetLen(len int) { func (v *sliceValueStruct) Set(src ArrayValue) { if !src.IsSlice() { - panic("can't set from fixed array"); + panic("can't set slice from array"); } s := src.(*sliceValueStruct); if !equalType(v.typ, s.typ) { @@ -619,10 +649,11 @@ func (v *arrayValueStruct) Cap() int { } func (v *arrayValueStruct) SetLen(len int) { + panicln("can't set len of array"); } func (v *arrayValueStruct) Set(src ArrayValue) { - panicln("can't set fixed array"); + panicln("can't set array"); } func (v *arrayValueStruct) Elem(i int) Value { @@ -659,10 +690,12 @@ func arrayCreator(typ Type, addr Addr) Value { // -- Map TODO: finish and test +// MapValue represents a map value. +// Its implementation is incomplete. type MapValue interface { Value; - Len() int; - Elem(key Value) Value; + Len() int; // The number of elements; currently always returns 0. + Elem(key Value) Value; // The value indexed by key; unimplemented. } type mapValueStruct struct { @@ -684,6 +717,8 @@ func (v *mapValueStruct) Elem(key Value) Value { // -- Chan +// ChanValue represents a chan value. +// Its implementation is incomplete. type ChanValue interface { Value; } @@ -698,10 +733,11 @@ func chanCreator(typ Type, addr Addr) Value { // -- Struct +// StructValue represents a struct value. type StructValue interface { Value; - Len() int; - Field(i int) Value; + Len() int; // The number of fields. + Field(i int) Value; // The Value of field i. } type structValueStruct struct { @@ -732,9 +768,10 @@ func structCreator(typ Type, addr Addr) Value { // -- Interface +// InterfaceValue represents an interface value. type InterfaceValue interface { Value; - Get() interface {}; + Get() interface {}; // Get the underlying interface{} value. } type interfaceValueStruct struct { @@ -751,6 +788,9 @@ func interfaceCreator(typ Type, addr Addr) Value { // -- Func + +// FuncValue represents a func value. +// Its implementation is incomplete. type FuncValue interface { Value; } @@ -801,6 +841,7 @@ func newValueAddr(typ Type, addr Addr) Value { return c(typ, addr); } +// NewInitValue creates a new, zero-initialized Value for the specified Type. func NewInitValue(typ Type) Value { // Some values cannot be made this way. switch typ.Kind() { @@ -819,6 +860,8 @@ func NewInitValue(typ Type) Value { return newValueAddr(typ, Addr(&data[0])); } +// NewSliceValue creates a new, zero-initialized slice value (ArrayValue) for the specified +// slice type (ArrayType), length, and capacity. func NewSliceValue(typ ArrayType, len, cap int) ArrayValue { if !typ.IsSlice() { return nil @@ -869,7 +912,7 @@ func copyArray(dst ArrayValue, src ArrayValue, n int) { } } - +// NewValue creates a new Value from the interface{} object provided. func NewValue(e interface {}) Value { value, typestring, indir := sys.Reflect(e); typ, ok := typecache[typestring]; |