interface的定义和声明方式

Golang interface关键字用来申明一组相关功能方法集合,是Go提供的抽象的主要手段。通过struct实现interface的所用声明来达到解耦,使用语法如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
go复制代码// 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, 可以使该函数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
go复制代码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实现的合法性,而无需在调用前检查其合法性。

本文转载自: 掘金

开发者博客 – 和开发相关的 这里全都有

0%