dtwkt46424 2019-09-06 12:40
浏览 16

在Go Wiki中解释go界面定义

I understand a bit a go and to certain extend understand interface as well(like how I do ducktyping in ruby) But reading the interface definition https://github.com/golang/go/wiki/CodeReviewComments

I'm clueless what is trying to convey.

1st: I did not understood the comment.

Go interfaces generally belong in the package that uses values of the interface type, not the package that implements those values.

2nd: I do not understand this

Do not define interfaces on the implementor side of an API "for mocking"; instead, design the API so that it can be tested using the public API of the real implementation.

3rd: I do not understand the example

Do not define interfaces before they are used: without a realistic example of usage, it is too difficult to see whether an interface is even necessary, let alone what methods it ought to contain.


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{ … } }

Can someone explain in plain and easier word the 3 things above.

  • 写回答

1条回答 默认 最新

  • douzhao6584 2019-09-06 19:55
    关注

    Forget analogies with other languages for the moment. Think of an interface like a contract - a set of requirements for the function that uses it.

    Say I define a function MakeNoise which needs to know the sound of the thing passed in, but otherwise doesn't care about it. Code below is all together, but imagine this in two separate packages - one for concrete types and one for MakeNoise.

    The MakeNoise function could take a specific type, but this limits it somewhat, might make testing harder etc, so often you might want it instead to define what it needs the type to do - in this case it just needs something with a Sound() method to call, other than that it doesn't care.

    Now on the Cat/Dog side, you might not care about MakeNoise, or even know about it yet, your animals should be defined separately and not care about any interfaces they conform with - those interfaces might not even have been written yet.

    So the Wiki is just saying that whoever writes MakeNoise should care about what it requires and put that in an interface, but whoever writes Cat/Dog should not care, and the interface should sit with MakeNoise, not with Cat/Dog. This means later someone might come and write a Giraffe in another package, and it can still be used with MakeNoise.

    The interface is a requirement, not a promise.

    https://play.golang.org/p/4r1wiXokKMb

    // 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())
    }
    
    评论

报告相同问题?

悬赏问题

  • ¥15 相敏解调 matlab
  • ¥15 求lingo代码和思路
  • ¥15 公交车和无人机协同运输
  • ¥15 stm32代码移植没反应
  • ¥15 matlab基于pde算法图像修复,为什么只能对示例图像有效
  • ¥100 连续两帧图像高速减法
  • ¥15 如何绘制动力学系统的相图
  • ¥15 对接wps接口实现获取元数据
  • ¥20 给自己本科IT专业毕业的妹m找个实习工作
  • ¥15 用友U8:向一个无法连接的网络尝试了一个套接字操作,如何解决?