Skip to content

interface

interface 里装的是「(动态类型, 动态值)」

指针接收者 与 值接收者

Choose pointer receivers unless you have a good reason not to.

*T 指针接收者

T 值接收者

定义

go
package main

import ( "fmt" )

type Dog struct {
    Name string
}

type Animal interface {
    Speak()
}

func (d Dog) Speak() {
    // if d == nil {
    //     fmt.Println("<no dog>")
    //     return
    // }
    fmt.Println("Woof! I'm", d.Name)
}

func main() {

	var a Animal 
    d := Dog{"Tom"}
	a = d
	a.Speak() 

	p := &Dog{"Jerry"}
	a = p
	// 因为 Speak 需要的是 Dog,而 p 是一个指针,但是可以通过 * 将指针转化为值,所以 Go 就帮我们做了
	a.Speak() 
}
go
package main

import ( "fmt" )

type Dog struct {
    Name string
}

type Animal interface {
    Speak()
}

func (d *Dog) Speak() {
    if d == nil {
        fmt.Println("<no dog>")
        return
    }
    fmt.Println("Woof! I'm", d.Name)
}

func main() {

	var a Animal 
    // d := Dog{"Tom"}
	// a = d // 报错:cannot use d (variable of struct type Dog) as Animal value in assignment: Dog does not implement Animal (method Speak has pointer receiver)
	// a.Speak() 

	// Speak 属于 *Dog,不属于 Dog!!!

	p := &Dog{"Jerry"}
	a = p
	a.Speak() 
}

例 2

go

type Abser interface {
	Abs() float64
}

func main() {
	var a Abser
	f := MyFloat(-math.Sqrt2)
	v := Vertex{3, 4}

	a = f  // a MyFloat 实现了 Abser
	a = &v // a *Vertex 实现了 Abser

	// 下面一行,v 是一个 Vertex(而不是 *Vertex)
	// 所以没有实现 Abser。
	a = v

	fmt.Println(a.Abs())
}

type MyFloat float64

func (f MyFloat) Abs() float64 {
	if f < 0 {
		return float64(-f)
	}
	return float64(f)
}

type Vertex struct {
	X, Y float64
}

func (v *Vertex) Abs() float64 {
	return math.Sqrt(v.X*v.X + v.Y*v.Y)
}

空接口

go
interface{}

空接口可保存任何类型的值。(因为每个类型都至少实现了零个方法。)