3 回答
TA贡献1799条经验 获得超6个赞
总结两个 答案:
该for环
for t.Kind() == reflect.Ptr {
t = t.Elem()
}
t.Elem()是反射等价于*t,所以t只要它持有另一个指针值,这个循环就会解除引用。在循环结束时,t将保存最后一个指针指向的值,不再是指针。
消息
使用不是指向接口的指针的值调用 [...]。 (*MyInterface)(nil)
该表达式(*MyInterface)(nil)只是预期参数的一个(措辞不佳)示例。
语法是转换的语法。在这种情况下,转换将尝试将值(在本例中nil)转换为给定类型 ( *MyInterface)。所以,
(*MyInterface)(nil)
会给你一个*MyInterface接口类型为MyInterface( play )的零值:
x := (*MyInterface)(nil)
InterfaceOf(x) // MyInterface
当然,这个值并没有指向有意义的地方。
接口实现的编译时检查
为避免混淆,您展示的构造
var _ SomeType = (*SomeInterface)(nil)
可能不是您想要的。我猜你想要这个:
var _ SomeInterface = (*SomeType)(nil)
此构造启用对某些类型的接口实现的编译时检查。因此,如果您正在编写某种类型的库,并且希望在不使用它的情况下满足接口,则可以使用它来确保您的结构实现了该接口。
为什么这有效
首先,var _ someType是一个将由编译器检查的变量,但不会出现在已编译的程序中,并且由于空白标识符_而无法访问:
空白标识符可以像声明中的任何其他标识符一样使用,但它不引入绑定,因此没有声明。
这使您可以在不干扰程序的其余部分的情况下声明任意数量的这些构造。
您可以通过编写以下代码声明任何类型的指针的零值:
(*T)(nil)
在 play 上检查这个例子。
接下来,可分配性表示x可分配给TifT是一个接口并x实现T。
所以总结一下:
T _ = (*x)(nil)
强制执行x工具T的一切将是一个错误。
TA贡献1995条经验 获得超2个赞
该for
循环与while
其他语言中的循环相同
第二件事只是转换的语法:
(*Point)(p) // p is converted to *Point
因为这个库是如何工作的,你只需要将指针传递给接口,for 循环然后取消引用它(如果我们传递类似 (***MyInterface)(nil)),然后 if 语句检查 ty[e 指向的是否是一个界面。
- 3 回答
- 0 关注
- 289 浏览
添加回答
举报