好的。我知道这是一个常见问题解答,我认为答案是“放弃,那样不行”,但我只是想确保我没有遗漏任何东西。
我仍然在思考使用接口的最佳实践和规则。我有不同包中的代码,我希望保持解耦,类似这样(不起作用,否则我不会在这里):
package A
type Foo struct {}
func (f *Foo) Bars() ([]*Foo, error) {
foos := make([]*Foo, 0)
// some loop which appends a bunch of related *Foo to foos
return foos, nil
}
package B
type Foolike interface {
Bars() []Foolike
}
func DoSomething(f Foolike) error {
// blah
}
有了这个,编译器抱怨:
cannot use f (type *A.Foo) as type Foolike in argument to B.DoSomething:
*A.Foo does not implement Foolike (wrong type for Bars method)
have Bars() ([]*A.Foo, error)
want Bars() ([]Foolike, error)
现在,我认为 []Foolike本身不是接口签名;它是 Foolike 接口切片的签名。我想我也神交编译器对待[] * A.Foo和[] Foolike不同的东西,因为...(喃喃内存分配,严格类型喃喃)。
我的问题是:有没有一种正确的方法来做我最终想要的,那就是让 B.DoSomething() 接受一个 *A.Foo 而不必导入 A 并在 B.DoSomething() 中使用 *A.Foo函数签名(或更糟,在接口定义中)?我并没有试图欺骗编译器或陷入疯狂的运行时技巧。我知道我可能会更改 Foo.Bars() 的实现以返回 []Foolike,但这似乎很愚蠢和错误(为什么 A 必须了解 B 的任何信息?这打破了解耦的重点!)。
不,那将不起作用,因为那样我就不能在 DoSomething() 中使用 Bars(),因为它没有在接口中定义。叹。
如果我只是做错了™,我会接受并想出其他办法,但我希望我只是没有了解它应该如何工作的某些方面。
大话西游666
相关分类