Golang interface关键字用来申明一组相关功能方法集合,是Go提供的抽象的主要手段。通过struct实现interface的所用声明来达到解耦,使用语法如下:
// package Interface
type InterfaceName interface{
Method1()string
}
// Package Implement
type Implement struct {}
func (i Implement) Method() string {
return "Hello, Interface"
}
// Package main
任何实现了Interface的struct都是可以使用该类型的变量引用。下面是对本人在interface定义和使用中提到的一些常用的“误用“的说明。
Don't define interface before needing it
预先定义的interface 即preemptive interface, 是不鼓励的,如果你只是实现一个功能,把功能暴露出来即可
Define Interface with Consumer, not Producer
通过前两条即可推理出,我们应该在Consumer中定义interface并且使用它作为函数的参数,在Producer中实现这些interface。这样还有一个好处是可以在consumer中很容易的mock 该producer,无需接触真正的实现。
Accepting interface & returns struct
Accepting interface
根据Postel’s law ”be liberal with what you accept, be conservative with what you do", 函数参数接收interface,扩大了函数的使用场景,能够接收更多的参数类型。例如下面example, CountCharA接口Reader, 可以使该函数
func CountCharA(r io.Reader) (int64, error){
buf [10]byte
for {
nr, err := r.Read(buf)
if nr > 0 {
for _, b := range buf[0:nr]{
if b == 'A'{
cnt++
}
}
}
if err != nil {
if err != EOF{
return 0, err
}
return cnt, nil
}
}
return cnt, nil
}
// Usage
CountCharA(bytes.NewStringBuffer("this statement contains 3a"))
CountCharA(ioutil.ReadFile("file.txt"))
Returns struct
返回struct,可以保证使用者能够最大限度的使用我们函数结果,如果因为struct可以自由的转换成该struct实现的所有interface,而且便于修改,
但是凡是都例外, error interface,
另外一个情况是,当返回struct包含有非法状态时, 通过返回interface来控制struct实现的合法性,而无需在调用前检查其合法性。