解释go wiki中的go接口定义

解释go wiki中的go接口定义,go,Go,我理解一点,在一定程度上也理解接口(比如我如何用ruby打字) 但是阅读接口定义 我不知道我想表达什么 第一:我不明白这个评论 Go接口通常属于使用接口类型值的包,而不是实现这些值的包 第二:我不明白 不要在API的实现方定义接口“用于模拟”;相反,设计API以便可以使用实际实现的公共API对其进行测试 第三:我不明白这个例子 在使用接口之前不要定义接口:如果没有实际的使用示例,就很难看出接口是否必要,更不用说它应该包含哪些方法了 有人能用简单易懂的词解释一下上面的三件事吗?暂时忘掉与其他语言的

我理解一点,在一定程度上也理解接口(比如我如何用ruby打字) 但是阅读接口定义

我不知道我想表达什么

第一:我不明白这个评论

Go接口通常属于使用接口类型值的包,而不是实现这些值的包

第二:我不明白

不要在API的实现方定义接口“用于模拟”;相反,设计API以便可以使用实际实现的公共API对其进行测试

第三:我不明白这个例子

在使用接口之前不要定义接口:如果没有实际的使用示例,就很难看出接口是否必要,更不用说它应该包含哪些方法了


有人能用简单易懂的词解释一下上面的三件事吗?

暂时忘掉与其他语言的类比。想象一个像合同一样的接口——使用它的功能的一组需求

假设我定义了一个函数MakeNoise,它需要知道传入的东西的声音,但是不关心它。下面的代码都在一起,但是想象一下这在两个单独的包中——一个用于具体类型,另一个用于MakeNoise

MakeNoise函数可以采用特定的类型,但这在某种程度上限制了它,可能会使测试变得更困难等等,因此您通常可能希望它定义它需要该类型做什么-在这种情况下,它只需要使用Sound()方法来调用,而不必在意

现在在猫/狗方面,您可能不关心MakeNoise,甚至还不知道它,您的动物应该单独定义,不关心它们符合的任何接口-这些接口可能还没有编写

因此,维基只是说,无论谁编写MakeNoise,都应该关心它需要什么,并将其放在一个界面中,但无论谁编写Cat/Dog,都不应该关心,界面应该与MakeNoise坐在一起,而不是与Cat/Dog坐在一起。这意味着以后可能会有人来用另一个包写一个长颈鹿,它仍然可以与MakeNoise一起使用

接口是一种要求,而不是承诺。


你不清楚这三篇摘录是怎么回事?老实说,这三篇都是因为如果没有一个正式的例子,我很难想象我脑海中的这些陈述。但是你不清楚这三篇是怎么回事?只是“我不明白这一点”并不能提供足够的信息来帮助你——你不明白的每一个呢?@Adrian说实话,我发现这些说法过于笼统,没有任何例子<代码>使用接口类型值的包这是什么意思。。举个例子会有帮助。第2点也一样。我没有具体的例子来理解这一点。我很抱歉,只有当我看到一个描述它的例子时,我才能理解这个陈述。

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{ … } }
// Here are some types which share one function. 
// They might have other functions too
package main

type Cat struct {}
func (d Cat) Sound() string {
    return "miao"
}

type Dog struct {}
func (d Dog) Sound() string {
    return "woof"
}

func main() {
    cat := Cat{}
    dog := Dog{}

    MakeNoise(cat)
    MakeNoise(dog)
}


// Sounder is the requirement for MakeNoise, so it lives with it.
// perhaps in a package together which knows nothing of cats and dogs.
type Sounder interface {
    Sound() string
}

// MakeNoise prints the sound of the thing
// it only cares the thing makes a Sound
func MakeNoise(thing Sounder) {
    println(thing.Sound())
}