我目前正在阅读https://github.com/codegangsta/inject go软件包的源代码,以了解此软件包的工作原理。
我有一些关于文件https://github.com/codegangsta/inject/blob/master/inject.go文件的问题,这些文件使用了我不理解的Go语言的某些元素,并且在文档中找不到精确的解释。
// InterfaceOf dereferences a pointer to an Interface type.
// It panics if value is not an pointer to an interface.
func InterfaceOf(value interface{}) reflect.Type {
t := reflect.TypeOf(value)
for t.Kind() == reflect.Ptr {
t = t.Elem()
}
if t.Kind() != reflect.Interface {
panic("Called inject.InterfaceOf with a value that is not a pointer to an interface. (*MyInterface)(nil)")
}
return t
}
我的第一个问题是关于for
循环。为什么它使用带有测试表达式的for循环?
第二个涉及恐慌功能中的消息。 (*MyInterface)(nil)
提到了“指向接口的指针”。当你检查一个类型实现一个结构时,我在go文档中只遇到类似'编译时检查结构'的结构:
var _ SomeType = (*SomeInterface)(nil)
我没有找到关于(*Interface)(nil)
语句和接口指针的任何信息。
我们应该如何解释这句话?与接口指针的关系是什么,我在哪里可以找到有关接口指针的信息?
答案 0 :(得分:4)
for
循环for t.Kind() == reflect.Ptr {
t = t.Elem()
}
t.Elem()
是等效于*t
的反射,所以只要它保存另一个指针值,这个循环就会解除引用t
。在循环结束时,t
将保存最后一个指针指向的值,而不是指针。
使用不是指向接口的指针的值调用[...]。
(*MyInterface)(nil)
表达式(*MyInterface)(nil)
只是表达参数的一个(措辞不当)示例。
语法是conversion的语法。在这种情况下,转换将尝试将值(在这种情况下为nil
)转换为给定类型(*MyInterface
)。所以,
(*MyInterface)(nil)
将为您提供*MyInterface
的零值,其接口类型为MyInterface
(play):
x := (*MyInterface)(nil)
InterfaceOf(x) // MyInterface
当然,这个值并没有指向有意义的地方。
为避免混淆,您展示的构造
var _ SomeType =(* SomeInterface)(nil)
可能不是你想要的。我想你想要这个:
var _ SomeInterface = (*SomeType)(nil)
此构造允许对某些类型的接口实现进行编译时检查。 因此,如果您正在编写某种类型的库,并且您希望在不使用的情况下满足接口 使用它,您可以使用它来确保您的结构实现接口。
为什么会这样?
首先,var _ someType
是一个将由编译器检查的变量
将不会出现在已编译的程序中,并且由于Blank Identifier _
:
空白标识符可以像声明中的任何其他标识符一样使用,但它不会引入绑定,因此不会声明。
这使您可以声明任意数量的这些结构而不会干扰 其余的计划。
您可以通过写:
来声明任何类型指针的零值(*T)(nil)
接下来,assignability表示x
如果T
是界面而T
实施x
,T
可分配给T _ = (*x)(nil)
。
总结一下:
x
强制T
实施{{1}},因为其他一切都是错误。
答案 1 :(得分:0)
for
循环与其他语言中的while
循环相同
第二件事只是转换的语法:
(*Point)(p) // p is converted to *Point
因为这个库如何工作你只需要将指针传递给接口,for循环然后取消引用它(如果我们传递类似(*** MyInterface)(nil)的东西)然后if语句检查是否ty [e指向是一个界面。
答案 2 :(得分:0)
for
循环用于连续取消引用类型,直到它不再是指针。这将处理类型获得额外间接的情况
例如play.golang.org/p/vR2gKNJChE
至于(*MyInterface)(nil)
,指向接口的指针总是 1 错误Go代码。我假设作者只是通过指向代码片段的接口来描述他的意思,因为它们非常罕见。
如果你仍然对禁忌类型感兴趣,那么Russ Cox有一些信息如何在引擎盖下完成所有这些工作:research.swtch.com/interfaces。您将很难找到有关使用指针到接口的信息,因为[ 1 ]。
(1)确定并非总是如此,但老实说,除非你是Go专业版,否则不要这样做。在这种情况下,不要告诉任何人。