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{}空接口可保存任何类型的值。(因为每个类型都至少实现了零个方法。)