【发布时间】:2018-08-13 06:35:31
【问题描述】:
假设在第 3 方库中,我们有一个接口和一个实现该接口的结构。我们还假设有一个以 ParentInterface 作为参数的函数,它对不同的类型有不同的行为。
type ParentInterface interface {
SomeMethod()
}
type ParentStruct struct {
...
}
func SomeFunction(p ParentInterface) {
switch x := p.Type {
case ParentStruct:
return 1
}
return 0
}
在我们的代码中,我们想使用这个接口,但是我们的行为增强了,所以我们将它嵌入到我们自己的结构中。编译器实际上允许我们直接在我的结构上调用关于 ParentInterface 的函数:
type MyStruct struct {
ParentInterface
}
parentStruct := ParentStruct{...}
myStruct := MyStruct{parentStruct}
parentStruct.SomeMethod() // Compiler OK.
myStruct.SomeMethod() // Compiler OK. Result is same. Great.
SomeFunction(parentStruct) // Compiler OK. Result is 1.
SomeFunction(myStruct.ParentInterface) // Compiler OK. Result is 1.
SomeFunction(myStruct) // Compiler OK. Result is 0. (!)
最后一种情况不是问题吗?我不止一次遇到过这种错误。因为我很乐意在我的代码中使用MyStruct 作为ParentInterface 的别名(这就是我首先定义它的原因),所以很难记住我们不能直接在MyStruct 上调用SomeFunction (编译器说我们可以!)。
那么避免这种错误的最佳做法是什么?或者它实际上是编译器的一个缺陷,它应该禁止使用SomeFunction(myStruct),因为结果无论如何都是不可信的?
【问题讨论】:
-
我不明白你在做什么。但是您描述的行为非常有意义,因为您正在检查 SomeFunction 中的基础类型。为了避免您看到的行为,可能只是不要这样做 - 而是依赖界面。但同样,我不知道你的目标,所以我真的不能说如何实现它。
标签: go methods struct interface embedding