我有一个int
/ string
/ bool
/ etc ..值存储在interface{}
中,并想确定它是否未初始化,这意味着它有一个值
0
""
false
nil
我该如何检查?
答案 0 :(得分:55)
据我所知,你想要的东西是:
func IsZeroOfUnderlyingType(x interface{}) bool {
return x == reflect.Zero(reflect.TypeOf(x)).Interface()
}
在谈论界面和nil
时,人们总是对两种截然不同且无关的事情感到困惑:
nil
接口值,它是一个没有基础值的接口值。这是接口类型的零值。nil
接口值(即它具有基础值),但其基础值是其基础类型的零值。例如基础值是nil
地图,nil
指针或0数字等我的理解是你在问第二件事。
更新:由于上述代码使用的是==
,因此不适用于 compare 的类型。我相信使用reflect.DeepEqual()
会使其适用于所有类型:
func IsZeroOfUnderlyingType(x interface{}) bool {
return reflect.DeepEqual(x, reflect.Zero(reflect.TypeOf(x)).Interface())
}
答案 1 :(得分:3)
interface{}
类型的zero value *仅为nil
,而非0
或""
或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 [ / Q]
答案 2 :(得分:1)
@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))
}
答案 3 :(得分:1)
Go 1.13(2019年第三季度)应简化检测过程:
新的
Value.IsZero()
方法报告一个Value是否是其类型的零值。
它在src/reflect/value.go
和commit c40bffd的CL 171337中实现,解决了issue 7501
请参见playground example(只要支持Go 1.13)