一. 接口
1. 概述
- 接口類型具體描述了一系列方法的集合
- 接口類型是一個抽象的類型,不會暴露出他代表的對象內(nèi)部值的結(jié)構(gòu)和對這個對象的支持的基礎(chǔ)操作集合,他只會展示出他們自己的方法。接口類型不能將其實例化
2. 接口的使用
2.1 接口的定義
type Humaner interfance{
SayHi()
}
- 接口里面的方法只有聲明沒有實現(xiàn),由其他的自定義類型實現(xiàn)
- 接口的命名習慣以er結(jié)尾
- 接口可以匿名嵌入其他接口或者嵌入到結(jié)構(gòu)中
2.2 接口的實現(xiàn)
package main
import "fmt"
type Humaner interface {
SayHi()
}
type Student struct {
name string
id int
}
func (s *Student)SayHi() {
fmt.Printf("Student %s SayHi ", s.name)
}
type Teacher struct {
name string
age int
}
func (t *Teacher)SayHi() {
fmt.Printf("Teacher %s SayHi ", t.name)
}
func main() {
var i Humaner
//只要實現(xiàn)了此接口方法類型,那么該類型的變量(或者接收者類型)就可以給i賦值
s := &Student{"mike" , 20}
i = s
i.SayHi()
t := &Teacher{"ricky" , 30}
i = t
t.SayHi()
}
/*
Student mike SayHi
Teacher ricky SayHi
*/
3. 接口的組合
3.1 接口嵌入
package main
import "fmt"
type Humaner interface {
SayHi()
}
type Personer interface {
Humaner //匿名字段 繼承了Humaner接口
Sing(lrc string)
}
type Student struct {
name string
id int
}
//Student 實現(xiàn)了該方法
func (s *Student)SayHi() {
fmt.Printf("Student %s SayHi \n", s.name)
}
func (s *Student)Sing(lrc string) {
fmt.Printf("Student %s Sing %s \n", s.name,lrc)
}
func main() {
var i Personer
s := &Student{"mike" , 66}
i = s
i.SayHi()
i.Sing("miao miao miao")
}
3.2 接口轉(zhuǎn)化
- 超集(Personer)可以轉(zhuǎn)化為子集(Humaner),但是子集(Humaner)不能轉(zhuǎn)化為超集(Personer)
func main() {
var iPro Personer //超集
iPro = &Student{"mike" , 66}
var i Humaner //子集
i = iPro //可以的 超集可以為子集
i.SayHi()
}
4. 空接口
- 不包含任何方法的接口是空接口
- ==所以的類型都實現(xiàn)了空接口==
var v1 interface{} = 1 //把int類型賦值給interface{}
var v2 interface{} = "abc" //把string類型賦值給interface{}
var v3 interface{} = &v2 //把*interface{}類型賦值給interface{}
var v4 interface{} = struct {
X int
}{1} //把int類型賦值給interface{}
- 空接口可以存儲任意類型的數(shù)值
- 當函數(shù)需要接受任意對象實例的時候,我們可以申明為空接口interface{}
5. 類型查詢
5.1 comma-ok斷言
package main
import (
"fmt"
)
type Student struct {
name string
}
func main() {
i := make([]interface{} , 3)
i[0] = 1
i[1] = "hello"
i[2] = Student{"mike" }
//類型查詢
for index , data := range i {
//判斷Value是不是int類型, 第一個返回的是值 第二個返回的結(jié)果
if value , ok := data.(int) ; ok == true {
fmt.Printf("x [%d] 類型為int , 內(nèi)容為%d \n" , index , value)
}else if value , ok := data.(string) ; ok == true {
fmt.Printf("x [%d] 類型為string , 內(nèi)容為 %s \n" , index , value)
}else if value , ok := data.(Student) ; ok == true {
fmt.Printf("x [%d] 類型為string , 內(nèi)容為%s \n" , index , value.name)
}
}
}
5.2 switch測試
for index , data := range i {
switch t := data.(type) {
case int:
fmt.Printf("x [%d] 類型為int , 內(nèi)容為%d \n" , index , t)
case string:
fmt.Printf("x [%d] 類型為int , 內(nèi)容為%s \n" , index , t)
case Student:
fmt.Printf("x [%d] 類型為int , 內(nèi)容為%s \n" , index , t.name)
}
}