我有一个int
/ string
/ bool
/etc.. 值存储在 an 中interface{}
,并想确定它是否未初始化,这意味着它的值是
0
""
false
- 或者
nil
我该如何检查?
我有一个int
/ string
/ bool
/etc.. 值存储在 an 中interface{}
,并想确定它是否未初始化,这意味着它的值是
0
""
false
nil
我该如何检查?
据我了解,你想要这样的东西:
func IsZeroOfUnderlyingType(x interface{}) bool {
return x == reflect.Zero(reflect.TypeOf(x)).Interface()
}
在谈论接口和nil
时,人们总是对两个非常不同且不相关的东西感到困惑:
nil
接口值,它是一个没有基础值的接口值。这是接口类型的零值。nil
接口值(即它有一个基础值),但它的基础值是其基础类型的零值。例如,基础值是nil
映射、nil
指针或 0 数字等。我的理解是你问的是第二件事。
更新:由于上面的代码使用==
,它不适用于不可比较的类型。我相信使用reflect.DeepEqual()
相反会使它适用于所有类型:
func IsZeroOfUnderlyingType(x interface{}) bool {
return reflect.DeepEqual(x, reflect.Zero(reflect.TypeOf(x)).Interface())
}
Go 1.13(2019 年第三季度)应该简化检测过程:
新
Value.IsZero()
方法报告 Value 是否是其类型的零值。
它是在提交 c40bffd和CL 171337src/reflect/value.go
中实现的,解决了问题 7501
请参阅操场示例(只要支持 Go 1.13)
type的零值*interface{}
是 only nil
, not 0
or ""
or false
。
package main
import "fmt"
func main() {
var v interface{}
fmt.Println(v == nil, v == 0, v == "", v == false)
}
(也http://play.golang.org/p/z1KbX1fOgB)
输出
true false false false
*: [Q]当内存被分配来存储一个值时,无论是通过声明还是调用make或new,并且没有提供显式初始化,内存被赋予默认初始化。这样一个值的每个元素都被设置为零值:布尔值为 false,整数为 0,浮点数为 0.0,字符串为 "",指针、函数、接口、切片、通道和映射为 nil。 /问]
@newacct 的答案无法检测到原始零值,调用reflect.Value.Interface()
它会导致错误。它可以reflect.Value.IsValid()
用来检查。
// IsValid reports whether v represents a value.
// It returns false if v is the zero Value.
// If IsValid returns false, all other methods except String panic.
// Most functions and methods never return an invalid value.
// If one does, its documentation states the conditions explicitly.
func (v Value) IsValid() bool
更新方法:
func IsZero(v reflect.Value) bool {
return !v.IsValid() || reflect.DeepEqual(v.Interface(), reflect.Zero(v.Type()).Interface())
}
func TestIsZero(t *testing.T) {
var p *string
v := reflect.ValueOf(p)
assert.Equal(t, true, v.IsValid())
assert.True(t, IsZero(v))
assert.Equal(t, uintptr(0), v.Pointer())
v = v.Elem()
assert.Equal(t, false, v.IsValid())
assert.True(t, IsZero(v))
}