go 的接口类型用于定义一组行为,其中每个行为都由一个方法声明表示。
接口类型中的方法声明只有方法签名而没有方法实体,而方法签名包括且仅包括方法的名称、参数列表和结果列表。
只要一种数据类型的方法集合中包含了Talk接口声明中的所有方法,那么它就一定是Talk接口的实现类型。
type Talk interface{ Hello(username stirng)string Talk(heard string)(saying string ,end bool, err error) } type myTalk string func (talk myTalk)Hello(username stirng)string{ //省略部分代码 } func (talk myTalk)Talk(heard string)(saying string ,end bool, err error){ //省略部分代码 }
上面示例中,与myTalk关联的所有方法都是指针方法,这意味着,myTalk类型并不是Talk接口的实现类型,*myTalk类型才是。
一个接口类型的变量可以被赋予任何实现类型的值
eg:
var talk Talk = new(myTalk)
内建函数new的功能是创建一个指定类型的值,并返回指向该值的指针。
若想确定变量talk中值是否属于“myTalk” 类型,则可以用类型断言来判断:
_,ok :=talk.(*myTalk)
go的数据类型之间并不存在继承关系,接口类型也是如此,不过,一个接口型的声明中可以嵌套任意其他接口类型。
type Chatbot interfaxce{ Name()string Regin()(string,error) Talk ReportError(err errors)string End() error }
moke/moke.go
package moke //interface definition type VowelsFinder interface { FindVowels() []rune } type MyString string //MyString implements VowelsFinder func (ms MyString) FindVowels() []rune { var vowels []rune for _, rune := range ms { if rune == 'a' || rune == 'e' || rune == 'i' || rune == 'o' || rune == 'u' { vowels = append(vowels, rune) } } return vowels }
main.go
package main import ( "fmt" "studycode/moke" ) func main() { name := moke.MyString("Sam Anderson") var v moke.VowelsFinder v = name // possible since MyString implements VowelsFinder fmt.Printf("Vowels are %c", v.FindVowels()) }
执行结果
示例二:
man/man.go
package man import ( "fmt" ) type People interface { GetAge() int GetName() string } type Man struct { } func (a *Man) GetAge() int { return 18 } func (a *Man) GetName() string { return "mike" } func TestPeople(p interface{}) { switch p.(type) { //变量.(type)只能在switch中使用 case People: fmt.Println("realize People interface") default: fmt.Println("realize People2 interface") } }
main.go
package main import ( "studycode/man" ) func main() { man1 := man.Man{} man.TestPeople(&man1) }
执行结果