duck typeing
隐式的实现接口的方法就等于实现了接口
main函数
package main import ( "fmt" "learngo/retriever/mock" "learngo/retriever/real" ) func main(){ var r Retriever r = mock.Retriever{"this is fyf"} r = real.Retriever{} fmt.Println(download(r)) } //interface中的函数不用加func type Retriever interface { Get(url string) string } func download(r Retriever) string{ return r.Get("http://www.imooc.com") }
实现接口一
package mock type Retriever struct { Contents string } //go语言中实现了Get(url string),就被认为实现了Retriever接口 func (r Retriever) Get(url string) string { return r.Contents }
实现接口二(拿下慕课网首页)
package real import ( "time" "net/http" "net/http/httputil" ) type Retriever struct { UserAgent string TimeOut time.Duration } func (r Retriever) Get(url string) string { resp , err :=http.Get(url) if err != nil{ panic(err) } result,err := httputil.DumpResponse(resp,true) resp.Body.Close() if err != nil { panic(err) } return string(result) }
Go语言里面有一个语法,可以直接判断是否是该类型的变量: value, ok= element.(T),这里value就是变量的值,ok是一个bool类型,element是interface变量,T是断言的类型。
如果element里面确实存储了T类型的数值,那么ok返回true,否则返回false。
package main import ( "fmt" "strconv" ) type Element interface{} type List [] Element type Person struct { name string age int } //定义了String方法,实现了fmt.Stringer func (p Person) String() string { return "(name: " + p.name + " - age: "+strconv.Itoa(p.age)+ " years)" } func main() { list := make(List, 3) list[0] = 1 // an int list[1] = "Hello" // a string list[2] = Person{"Dennis", 70} for index, element := range list { if value, ok := element.(int); ok { fmt.Printf("list[%d] is an int and its value is %d ", index, value) } else if value, ok := element.(string); ok { fmt.Printf("list[%d] is a string and its value is %s ", index, value) } else if value, ok := element.(Person); ok { fmt.Printf("list[%d] is a Person and its value is %s ", index, value) } else { fmt.Println("list[%d] is of a different type", index) } } }