mirror of
https://github.com/golang/go
synced 2024-11-17 13:54:46 -07:00
reflect: add Value.{CanInt, CanUint, CanFloat, CanComplex}
As discussed in #47658, Value already has CanAddr and CanInterface to test if a call to Addr or Inteface, respectively, does not result in a panic. Therefore we add CanInt, CanUint, CanFloat and CanComplex to ease the test for a possible panic in calling, respectively, Int, Uint, Float and Complex. Fixes #47658 Change-Id: I58b77d77e6eec9f34234e985f631eab72b5b935e Reviewed-on: https://go-review.googlesource.com/c/go/+/352131 Run-TryBot: Ian Lance Taylor <iant@golang.org> TryBot-Result: Go Bot <gobot@golang.org> Trust: David Chase <drchase@google.com> Trust: Brad Fitzpatrick <bradfitz@golang.org> Reviewed-by: Keith Randall <khr@golang.org>
This commit is contained in:
parent
8e34d77957
commit
04f7521b0a
@ -127,6 +127,10 @@ func TestIntendedInlining(t *testing.T) {
|
||||
"ValidRune",
|
||||
},
|
||||
"reflect": {
|
||||
"Value.CanInt",
|
||||
"Value.CanUint",
|
||||
"Value.CanFloat",
|
||||
"Value.CanComplex",
|
||||
"Value.CanAddr",
|
||||
"Value.CanSet",
|
||||
"Value.CanInterface",
|
||||
|
@ -376,6 +376,75 @@ func TestMapIterSet(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestCanIntUintFloatComplex(t *testing.T) {
|
||||
type integer int
|
||||
type uinteger uint
|
||||
type float float64
|
||||
type complex complex128
|
||||
|
||||
var ops = [...]string{"CanInt", "CanUint", "CanFloat", "CanComplex"}
|
||||
|
||||
var testCases = []struct {
|
||||
i interface{}
|
||||
want [4]bool
|
||||
}{
|
||||
// signed integer
|
||||
{132, [...]bool{true, false, false, false}},
|
||||
{int8(8), [...]bool{true, false, false, false}},
|
||||
{int16(16), [...]bool{true, false, false, false}},
|
||||
{int32(32), [...]bool{true, false, false, false}},
|
||||
{int64(64), [...]bool{true, false, false, false}},
|
||||
// unsigned integer
|
||||
{uint(132), [...]bool{false, true, false, false}},
|
||||
{uint8(8), [...]bool{false, true, false, false}},
|
||||
{uint16(16), [...]bool{false, true, false, false}},
|
||||
{uint32(32), [...]bool{false, true, false, false}},
|
||||
{uint64(64), [...]bool{false, true, false, false}},
|
||||
{uintptr(0xABCD), [...]bool{false, true, false, false}},
|
||||
// floating-point
|
||||
{float32(256.25), [...]bool{false, false, true, false}},
|
||||
{float64(512.125), [...]bool{false, false, true, false}},
|
||||
// complex
|
||||
{complex64(532.125 + 10i), [...]bool{false, false, false, true}},
|
||||
{complex128(564.25 + 1i), [...]bool{false, false, false, true}},
|
||||
// underlying
|
||||
{integer(-132), [...]bool{true, false, false, false}},
|
||||
{uinteger(132), [...]bool{false, true, false, false}},
|
||||
{float(256.25), [...]bool{false, false, true, false}},
|
||||
{complex(532.125 + 10i), [...]bool{false, false, false, true}},
|
||||
// not-acceptable
|
||||
{"hello world", [...]bool{false, false, false, false}},
|
||||
{new(int), [...]bool{false, false, false, false}},
|
||||
{new(uint), [...]bool{false, false, false, false}},
|
||||
{new(float64), [...]bool{false, false, false, false}},
|
||||
{new(complex64), [...]bool{false, false, false, false}},
|
||||
{new([5]int), [...]bool{false, false, false, false}},
|
||||
{new(integer), [...]bool{false, false, false, false}},
|
||||
{new(map[int]int), [...]bool{false, false, false, false}},
|
||||
{new(chan<- int), [...]bool{false, false, false, false}},
|
||||
{new(func(a int8)), [...]bool{false, false, false, false}},
|
||||
{new(struct{ i int }), [...]bool{false, false, false, false}},
|
||||
}
|
||||
|
||||
for i, tc := range testCases {
|
||||
v := ValueOf(tc.i)
|
||||
got := [...]bool{v.CanInt(), v.CanUint(), v.CanFloat(), v.CanComplex()}
|
||||
|
||||
for j := range tc.want {
|
||||
if got[j] != tc.want[j] {
|
||||
t.Errorf(
|
||||
"#%d: v.%s() returned %t for type %T, want %t",
|
||||
i,
|
||||
ops[j],
|
||||
got[j],
|
||||
tc.i,
|
||||
tc.want[j],
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestCanSetField(t *testing.T) {
|
||||
type embed struct{ x, X int }
|
||||
type Embed struct{ x, X int }
|
||||
|
@ -1122,6 +1122,16 @@ func (v Value) Close() {
|
||||
chanclose(v.pointer())
|
||||
}
|
||||
|
||||
// CanComplex reports whether Complex can be used without panicking.
|
||||
func (v Value) CanComplex() bool {
|
||||
switch v.kind() {
|
||||
case Complex64, Complex128:
|
||||
return true
|
||||
default:
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
// Complex returns v's underlying value, as a complex128.
|
||||
// It panics if v's Kind is not Complex64 or Complex128
|
||||
func (v Value) Complex() complex128 {
|
||||
@ -1249,6 +1259,16 @@ func (v Value) FieldByNameFunc(match func(string) bool) Value {
|
||||
return Value{}
|
||||
}
|
||||
|
||||
// CanFloat reports whether Float can be used without panicking.
|
||||
func (v Value) CanFloat() bool {
|
||||
switch v.kind() {
|
||||
case Float32, Float64:
|
||||
return true
|
||||
default:
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
// Float returns v's underlying value, as a float64.
|
||||
// It panics if v's Kind is not Float32 or Float64
|
||||
func (v Value) Float() float64 {
|
||||
@ -1310,6 +1330,16 @@ func (v Value) Index(i int) Value {
|
||||
panic(&ValueError{"reflect.Value.Index", v.kind()})
|
||||
}
|
||||
|
||||
// CanInt reports whether Int can be used without panicking.
|
||||
func (v Value) CanInt() bool {
|
||||
switch v.kind() {
|
||||
case Int, Int8, Int16, Int32, Int64:
|
||||
return true
|
||||
default:
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
// Int returns v's underlying value, as an int64.
|
||||
// It panics if v's Kind is not Int, Int8, Int16, Int32, or Int64.
|
||||
func (v Value) Int() int64 {
|
||||
@ -2391,6 +2421,16 @@ func (v Value) Type() Type {
|
||||
return v.typ.typeOff(m.mtyp)
|
||||
}
|
||||
|
||||
// CanUint reports whether Uint can be used without panicking.
|
||||
func (v Value) CanUint() bool {
|
||||
switch v.kind() {
|
||||
case Uint, Uint8, Uint16, Uint32, Uint64, Uintptr:
|
||||
return true
|
||||
default:
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
// 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 (v Value) Uint() uint64 {
|
||||
|
Loading…
Reference in New Issue
Block a user