TOC

Go interface

不像我们常见的一些语言,实现接口需要显式声明,比如 PHP:

interface Animal {
    public function move();
    public function makeSound();
}

class Dog implements Animal {
    public function move() {
        echo "Dog is moving\n";
    }

    public function makeSound() {
        echo "Woof\n";
    }
}

Go 不需要声明,说到不如做到,实现了所有接口方法就行了。
PS:我还是觉得写出来比较好一些,阅读代码的时候更加一目了然,也没有什么副作用。

示例

package main

import "fmt"

type Animal interface {
    move() string
    makeSound() string
}

type Dog struct {
    name string
}

func (d Dog) move() string {
    return fmt.Sprintf("%s is running", d.name)
}

func (d Dog) makeSound() string {
    return "woof"
}

func main() {
    dog := Dog{name: "Fido"}

    // 判断接口实现关系
    _, ok := interface{}(dog).(Animal)
    if ok {
        fmt.Printf("%T is Animal\n", dog)
    } else {
        fmt.Printf("%T is NOT Animal\n", dog)
    }

    fmt.Println(dog.move())
    fmt.Println(dog.makeSound())
}

interface{}

interface{} says nothing.

Go 谚语第六条是什么意思?

我的理解:

interface{} 可以表示任意类型,有时使用起来会很方便。
但是必须注意这意味着对类型没有任何约束,无论从程序的严谨度还是代码可读性上讲,都是有害的。
如何可以的话,编码中应当尽量采用范围小一些的接口,就比如到处可见的 io.Writer 接口,它有各类实现:

  • bytes.Buffer
  • bufio.Writer
  • os.File
  • compress/gzip.Writer
  • crypto/cipher.StreamWriter
  • encoding/csv.Writer
  • net/http.ResponseWriter
  • archive/zip.Writer
  • image/png.Encoder