我知道我可以通过反射来获取对象的值,然后使用类型断言使用以下方法来获取实际对象:
obj := new(User) out := reflect.ValueOf(obj).Elem().Interface().(User) fmt.Println(out == *obj) // true
但是,如果我不知道对象的类型是User,该怎么办呢?说它在像这样的函数中:
User
func Foo(obj interface{}) bool { // out := reflect.ValueOf(obj).Elem().Interface().( ... ) return out == *obj } func main() { obj := new(User) fmt.Println(Foo(obj)) }
在Foo函数内部,您将永远不知道实际上将传递哪种类型的对象,那么如何完成类型声明?
Foo
你不能 类型断言使您可以利用语言为您提供的静态类型检查,即使您有一个接口,其类型不是静态检查的。基本上它是这样的:
你有一些静态类型的变量s,它有型t。如果您试图像其他类型一样使用,则编译器通过拒绝编译来强制s始终具有类型的保证,因为这会破坏保证。t``s
s
t
t``s
您还可以使用一些接口变量i。i的类型在编译时未知,因此编译器无法保证分配i给s不会破坏s具有type 的保证t。但是,您 可以 做的是类型声明。类型断言通过说:“好吧,我会在运行时检查,并且仅在类型匹配时才进行赋值”,从而避免了该问题。编译器可以这样做,因为它知道只有在类型匹配时才会发生分配,这意味着它仍然可以保证s具有type t。因此,基本上在运行时发生的是:
i
if (i has type t) { s = i } else { s = t{} // Zero value of t }
您无法要求的原因是,编译器 必须 知道您要针对哪种类型进行检查,以便编译器可以编写我上面给出的伪代码的检查。不知道是什么t,就没有办法知道s应该是什么静态类型,也没有办法检查它是否正确。