接口的实现
package main
import (
"fmt"
)
// 接口中是方法的定义
type Pet interface {
SetName(name string)
Name() string
}
type Dog struct {
name string
}
// *Dog 的方法集合中有 Pet 接口的全部方法
// *Dog 就是 Pet 接口类型的实现类型,这种无侵入式的接口实现方式叫”鸭子类型“
func (dog *Dog) SetName(name string) {
dog.name = name
}
// Dog 的方法集合中仅有 Pet 接口中的 Name 方法,所以没有实现 Pet 接口
func (dog Dog) Name() string {
return dog.name
}
func main(){
dog := Dog {"little dog"}
_, ok := interface{}(dog).(Pet) // 不能转换
fmt.Printf("Dog implements interface Pet: %v\n", ok)
_, ok = interface{}(&dog).(Pet) // 可以转换
fmt.Printf("*Dog implements interface Pet: %v\n", ok)
fmt.Println()
// pet 的静态类型为 Pet,动态类型为 *Dog
var pet Pet = &dog // 赋值成功,因为 *Dog 是 Pet 的实现
fmt.Printf("name: %q.\n", pet.Name())
}
注:接口变量被赋值后,会包含两个指针,一个指向动态值,一个指向类型信息。
接口之间的组合
接口类型间的嵌入不会涉及方法间的”屏蔽“,只要组合的接口之间有同门的方法就会产生冲突。
package main
import (
"fmt"
)
type Animal interface {
ScientificName() string
Category() string
}
type Named interface {
Name() string
}
// 包含以上两个接口
type Pet interface {
Animal
Named
}
// 实现了接口 Named
type PetTag struct {
name string
owner string
}
func (pt PetTag) Name() string {
return pt.name
}
func(pt PetTag) Owner() string {
return pt.owner
}
// 实现了接口 Pet
type Dog struct {
PetTag
scientificName string
}
func (dog Dog) ScientificName() string {
return dog.scientificName
}
func (dog Dog) Category() string {
return "dog"
}
func main(){
petTag := PetTag{name: "little pig"}
_, ok := interface{}(petTag).(Named) // 可以转换
fmt.Printf("PetTag implements interface Named: %v\n", ok)
dog := Dog {
PetTag: petTag,
scientificName: "Labrador Retriver",
}
_, ok = interface{}(dog).(Animal) // 可以转换
fmt.Printf("Dog implements interface Animal: %v\n", ok)
_, ok = interface{}(dog).(Named) // 可以转换
fmt.Printf("Dog implements interface Named: %v\n", ok)
_, ok = interface{}(dog).(Pet) // 可以转换
fmt.Printf("Dog implements interface Pet: %v\n", ok)
}