mirror of
https://github.com/golang/go
synced 2024-10-04 12:21:26 -06:00
fb175cf77e
Type is now an interface that implements all the possible type methods. Instead of a type switch on a reflect.Type t, switch on t.Kind(). If a method is invoked on the wrong kind of type (for example, calling t.Field(0) when t.Kind() != Struct), the call panics. There is one method renaming: t.(*ChanType).Dir() is now t.ChanDir(). Value is now a struct value that implements all the possible value methods. Instead of a type switch on a reflect.Value v, switch on v.Kind(). If a method is invoked on the wrong kind of value (for example, calling t.Recv() when t.Kind() != Chan), the call panics. Since Value is now a struct, not an interface, its zero value cannot be compared to nil. Instead of v != nil, use v.IsValid(). Instead of other uses of nil as a Value, use Value{}, the zero value. Many methods have been renamed, most due to signature conflicts: OLD NEW v.(*ArrayValue).Elem v.Index v.(*BoolValue).Get v.Bool v.(*BoolValue).Set v.SetBool v.(*ChanType).Dir v.ChanDir v.(*ChanValue).Get v.Pointer v.(*ComplexValue).Get v.Complex v.(*ComplexValue).Overflow v.OverflowComplex v.(*ComplexValue).Set v.SetComplex v.(*FloatValue).Get v.Float v.(*FloatValue).Overflow v.OverflowFloat v.(*FloatValue).Set v.SetFloat v.(*FuncValue).Get v.Pointer v.(*InterfaceValue).Get v.InterfaceData v.(*IntValue).Get v.Int v.(*IntValue).Overflow v.OverflowInt v.(*IntValue).Set v.SetInt v.(*MapValue).Elem v.MapIndex v.(*MapValue).Get v.Pointer v.(*MapValue).Keys v.MapKeys v.(*MapValue).SetElem v.SetMapIndex v.(*PtrValue).Get v.Pointer v.(*SliceValue).Elem v.Index v.(*SliceValue).Get v.Pointer v.(*StringValue).Get v.String v.(*StringValue).Set v.SetString v.(*UintValue).Get v.Uint v.(*UintValue).Overflow v.OverflowUint v.(*UintValue).Set v.SetUint v.(*UnsafePointerValue).Get v.Pointer v.(*UnsafePointerValue).Set v.SetPointer Part of the motivation for this change is to enable a more efficient implementation of Value, one that does not allocate memory during most operations. To reduce the size of the CL, this CL's implementation is a wrapper around the old API. Later CLs will make the implementation more efficient without changing the API. Other CLs to be submitted at the same time as this one add support for this change to gofix (4343047) and update the Go source tree (4353043). R=gri, iant, niemeyer, r, rog, gustavo, r2 CC=golang-dev https://golang.org/cl/4281055
97 lines
2.1 KiB
Go
97 lines
2.1 KiB
Go
// 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.
|
|
|
|
// 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_test
|
|
|
|
import (
|
|
. "reflect"
|
|
"strconv"
|
|
)
|
|
|
|
// valueToString returns a textual representation of the reflection value val.
|
|
// For debugging only.
|
|
func valueToString(val Value) string {
|
|
var str string
|
|
if !val.IsValid() {
|
|
return "<zero Value>"
|
|
}
|
|
typ := val.Type()
|
|
switch val.Kind() {
|
|
case Int, Int8, Int16, Int32, Int64:
|
|
return strconv.Itoa64(val.Int())
|
|
case Uint, Uint8, Uint16, Uint32, Uint64, Uintptr:
|
|
return strconv.Uitoa64(val.Uint())
|
|
case Float32, Float64:
|
|
return strconv.Ftoa64(val.Float(), 'g', -1)
|
|
case Complex64, Complex128:
|
|
c := val.Complex()
|
|
return strconv.Ftoa64(real(c), 'g', -1) + "+" + strconv.Ftoa64(imag(c), 'g', -1) + "i"
|
|
case String:
|
|
return val.String()
|
|
case Bool:
|
|
if val.Bool() {
|
|
return "true"
|
|
} else {
|
|
return "false"
|
|
}
|
|
case Ptr:
|
|
v := val
|
|
str = typ.String() + "("
|
|
if v.IsNil() {
|
|
str += "0"
|
|
} else {
|
|
str += "&" + valueToString(v.Elem())
|
|
}
|
|
str += ")"
|
|
return str
|
|
case Array, Slice:
|
|
v := val
|
|
str += typ.String()
|
|
str += "{"
|
|
for i := 0; i < v.Len(); i++ {
|
|
if i > 0 {
|
|
str += ", "
|
|
}
|
|
str += valueToString(v.Index(i))
|
|
}
|
|
str += "}"
|
|
return str
|
|
case Map:
|
|
t := typ
|
|
str = t.String()
|
|
str += "{"
|
|
str += "<can't iterate on maps>"
|
|
str += "}"
|
|
return str
|
|
case Chan:
|
|
str = typ.String()
|
|
return str
|
|
case Struct:
|
|
t := typ
|
|
v := val
|
|
str += t.String()
|
|
str += "{"
|
|
for i, n := 0, v.NumField(); i < n; i++ {
|
|
if i > 0 {
|
|
str += ", "
|
|
}
|
|
str += valueToString(v.Field(i))
|
|
}
|
|
str += "}"
|
|
return str
|
|
case Interface:
|
|
return typ.String() + "(" + valueToString(val.Elem()) + ")"
|
|
case Func:
|
|
v := val
|
|
return typ.String() + "(" + strconv.Uitoa64(uint64(v.Pointer())) + ")"
|
|
default:
|
|
panic("valueToString: can't print type " + typ.String())
|
|
}
|
|
return "valueToString: can't happen"
|
|
}
|