定義
接口是一種抽象的類型
理解爲關聯更加準確
接口的實現: 一個對象只要全部實現了接口中的方法, 就是實現了這個接口
給接口命名時, 通常在單詞後加"er"
示例
package main
import "fmt"
// go語言中, 接口(interface)是一種抽象的類型, 理解爲協議或約定更加準確
// Cat 貓
type Cat struct{}
// Dog 狗
type Dog struct{}
// Say 喵喵喵
func (c Cat) Say() string {
return "喵喵喵"
}
// Say 汪汪汪
func (d Dog) Say() string {
return "汪汪汪"
}
// Sayer 所有會說話的(有Say方法的)
type Sayer interface {
Say() string // 需要實現的方法名(參數) 返回值
}
func main() {
c := Cat{}
d := Dog{}
var animallist []Sayer
animallist = append(animallist, c, d)
for _, v := range animallist {
fmt.Println(v.Say())
}
}
接口的嵌套
type speaker interface {
speak()
}
type mover interface {
move()
}
// animal接口中嵌套了speaker接口和mover接口, 也就是說實現了animal接口必須同時實現speaker和mover
type animaler interface {
speaker
mover
}
空接口
沒有定義任何方法的接口, 因此, 任何類型都實現了空接口
空接口類型的變量, 可以存儲任意類型的變量
package main
import (
"fmt"
"time"
)
// 空interface
type cat struct{}
func main() {
var x interface{}
x = 10
fmt.Printf("%T, 值爲%v\n", x, x)
x = "10"
fmt.Printf("%T, 值爲%v\n", x, x)
x = time.Second
fmt.Printf("%T, 值爲%v\n", x, x)
x = cat{}
fmt.Printf("%T, 值爲%v\n", x, x)
x = "哈哈"
// 注意! 此時x爲interface類型, 所以&x類型爲*interface{}
fmt.Printf("%T, 值爲%v\n", x, x)
}
類型斷言
- if
func showType(x interface{}) { // 作爲參數可以接收一切類型
// 因爲這個函數可以接收任意類型的變量
// 類型斷言
v, ok := x.(int)
if !ok {
// 說明不是int
} else {
fmt.Println("是int類型, 值爲:", v)
}
}
- switch
func showType(x interface{}) { // 作爲參數可以接收一切類型
// fmt.Printf("Type: %T, 值: %v\n", x, x)
// 因爲這個函數可以接收任意類型的變量
// 類型斷言
switch v := x.(type) {
case string:
fmt.Printf("類型爲string, 值爲%v\n", v)
case int:
fmt.Printf("類型爲int, 值爲%v\n", v)
case bool:
fmt.Printf("類型爲bool, 值爲%v\n", v)
case *string:
fmt.Printf("類型爲string指針, 值爲%v\n", v)
case cat:
fmt.Printf("類型爲cat結構體, 值爲%v\n", v)
default:
fmt.Println("不是string, int, bool")
}
}
值接收者和指針接收者實現接口的區別
值接收者
package main
import "fmt"
// 實現接口時, 使用指針接收者和值接收者的區別
type animal interface {
move() string
}
type cat struct {
name string
}
// 值接收者
func (c cat) move() string { // 由值接收者實現move方法
return "我能動"
}
func main() {
var x animal
hh := cat{name: "花花"} // 實例化一個cat類型
x = hh // 由於是值接受者實現的move方法, 所以hh實現了接口
tom := &cat{"tom"} // 實例化, 並將指針賦值給tom
x = tom // 通過go語言語法糖內部實現, 將tom轉換成*tom
fmt.Println(x.move())
fmt.Println(tom.move()) // (*tom).move()
}
指針接收者
package main
import "fmt"
// 實現接口時, 使用指針接收者和值接收者的區別
type animal interface {
// speak() string
move() string
}
type cat struct {
name string
}
func (c *cat) move() string {
return "我能動"
}
func main() {
var x animal
tom := &cat{name: "tom"} // 實例化, 並將指針賦值給tom
x = tom // 實現animal接口的是*cat類型, tom此時爲cat類型指針
fmt.Println(x.move())
}