## 常见写法
经常看到许多人的写法
```go
package animals
type Animal interface {
Speak() string
}
//实现animal这个接口
type Dog struct{}
func (a Dog) Speak() string { return "woof" }
```
```go
package circus
import "animals"
func Perform(a animal.Animal) string { return a.Speak() }
```
这种写法很像java 风格,`Java-style`接口使用方式。解读上面的代码步骤
- 定义了一个`Animal`的接口
- 定义了一个`Dog`的结构体
- `Dog`的结构体有一个方法为`Speak`,这样`Dog`这个结构体实现了`Animal`这个接口
以上写法可以概括为“编写类型以实现接口”。
- 很明显它只有一种类型可以实现接口而没有明显的扩展方式。
- 参数通常采用具体类型而不是接口类型。
## 更建议的写法
Go 的接口,不是编写类型来实现接口,而是编写接口满足需求。就拿上面的代码为例,不是在animals中定义Animal,而是在使用的位置来定义接口。
```go
package animals
type Dog struct{}
func (a Dog) Speaks() string { return "woof" }
```
```go
package circus
type Speaker interface {
Speak() string
}
func Perform(a Speaker) string { return a.Speak() }
```
- 定义类型
- 在使用的位置定义接口
这种是方式减少了包`animals` 对组件的依赖。减少依赖可以有助于构建一个更强壮的程序。
## Postel 定律
编写优秀软件的好准则之一Postel 定律。这个翻译有很多版本不同的环境都有不同的理解。贴原文
> “Be conservative with what you do, be liberal with you accept”
在Go中的理解
> 接收接口,返回结构(Accept interfaces,return structs)
Go的谚语中,Rob pike 说过这样一句话
> “the empty interface says nothing“ - Rob Pike
写go更多应该按照的go的思想 和行为来编写代码。而不是保持过多原有的思想。
有疑问加站长微信联系(非本文作者)