packagemainimport"fmt"typePetinterface{SetName(namestring)Name()stringCategory()string}typeDogstruct{namestring// 名字。}func(dog *Dog)SetName(namestring){dog.name=name}func(dog Dog)Name()string{returndog.name}func(dog Dog)Category()string{return"dog"}funcmain(){// 示例1。dog:=Dog{"little pig"}_,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()// 示例2。varpetPet=&dogfmt.Printf("This pet is a %s, the name is %q.\n",pet.Category(),pet.Name())}
这里先声明了一个 Dog 类型的变量 dog1,并且没有对它进行初始化。这时该变量的值是什么?显然是nil。然后我把该变量赋给了dog2,后者的值此时也必定是nil。把dog2赋给Pet类型的变量pet之后,变量pet的值不为 nil,虽然被包装的动态值是nil,但是pet的值却不会是nil,因为这个动态值只是pet值的一部分而已。这时的pet的动态类型就存在了,是\Dog。我们可以通过fmt.Printf函数和占位符%T来验证这一点,另外reflect包的TypeOf函数也可以起到类似的作用。
Dog implements interface Pet: false
*Dog implements interface Pet: true
This pet is a dog, the name is "little pig".
dog := Dog{"little pig"}
var pet Pet = &dog
dog := Dog{"little pig"}
var pet Pet = dog
dog.SetName("monster")
var dog1 *Dog
fmt.Println("The first dog is nil. [wrap1]")
dog2 := dog1
fmt.Println("The second dog is nil. [wrap1]")
var pet Pet = dog2
if pet == nil {
fmt.Println("The pet is nil. [wrap1]")
} else {
fmt.Println("The pet is not nil. [wrap1]")
}
type Animal interface {
ScientificName() string
Category() string
}
type Pet interface {
Animal
Name() string
}