我理解了一点,在某种程度上也理解了接口(比如我如何用ruby做ducktyping),但是阅读接口定义https://github.com/golang/go/wiki/CodeReviewComments
我不知道你想表达什么。
第一:我不明白评论。
Go语言接口通常属于使用接口类型值的包,而不是实现这些值的包。
第二:我不明白
不要在API的实现方定义接口"用于模拟";相反,应该设计API,以便可以使用实际实现的公共API对其进行测试。
第三:我不明白这个例子
在使用接口之前不要定义接口:如果没有一个实际的使用例子,就很难看出接口是否必要,更不用说它应该包含什么方法了。
package consumer // consumer.go
type Thinger interface { Thing() bool }
func Foo(t Thinger) string { ..... }
package consumer // consumer_test.go
type fakeThinger struct{ … }
func (t fakeThinger) Thing() bool { … }
if Foo(fakeThinger{…}) == "x" { ... }
// DO NOT DO IT!!!
package producer
type Thinger interface { Thing() bool }
type defaultThinger struct{ … }
func (t defaultThinger) Thing() bool { … }
func NewThinger() Thinger { return defaultThinger{ … } }
package producer
type Thinger struct{ … }
func (t Thinger) Thing() bool { … }
func NewThinger() Thinger { return Thinger{ … } }
有人能用简单明了的话解释一下上面的三件事吗?
1条答案
按热度按时间4nkexdtk1#
暂时忘掉与其他语言的类比,把接口想象成一个契约-* 对使用它的函数的一组需求。
假设我定义了一个函数MakeNoise,它需要知道传入的东西的声音,但在其他方面并不关心它。下面的代码是一起的,但想象一下这是在两个单独的包中-一个用于具体类型,一个用于MakeNoise。
MakeNoise函数可以接受特定的类型,但这会在一定程度上限制它,可能会使测试更加困难等,所以通常您可能希望它定义它需要该类型做什么-在这种情况下,它只需要使用Sound()方法调用一些东西,除此之外它不关心。
现在,在猫/狗方面,您可能不关心MakeNoise,甚至还不知道它,您的动物应该单独定义,不关心它们符合的任何接口-这些接口可能还没有编写。
所以Wiki就是说不管是谁写的MakeNoise都应该关心它需要什么并把它放在一个接口里,但是不管是谁写的Cat/Dog都不应该关心,接口应该和MakeNoise放在一起,而不是和Cat/Dog放在一起。这意味着以后有人可能会在另一个包里写一个Giraffe,它仍然可以和MakeNoise一起使用。
接口是一项要求,而不是承诺。
https://play.golang.org/p/4r1wiXokKMb