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)
}
执行结果
