结构体的方法
package main
import (
"fmt"
)
type AnimalCategory struct {
kingdom string // 界
phylum string // 门
class string // 纲
order string // 目
family string // 科
genus string // 属
species string // 种
}
// String 方法隶属于 AnimalCategory 类型
// String 的功能是提供当前值的字符串表示形式
func (ac AnimalCategory) String() string {
return fmt.Sprintf("%s%s%s%s%s%s%s",
ac.kingdom, ac.phylum, ac.class, ac.order,
ac.family, ac.genus, ac.species)
}
func main(){
category := AnimalCategory{species: "cat"}
fmt.Printf("The animal category: %s\n", category)
}
结构体的嵌入字段
package main
import (
"fmt"
)
type AnimalCategory struct {
kingdom string // 界
phylum string // 门
class string // 纲
order string // 目
family string // 科
genus string // 属
species string // 种
}
// String 方法隶属于 AnimalCategory 类型
// String 的功能是提供当前值的字符串表示形式
func (ac AnimalCategory) String() string {
return fmt.Sprintf("%s%s%s%s%s%s%s",
ac.kingdom, ac.phylum, ac.class, ac.order,
ac.family, ac.genus, ac.species)
}
type Animal struct {
scientificName string // 学名
// 只有类型名,是嵌入字段
// 嵌入字段的方法会被无条件整合到被嵌入类型的方法集中
AnimalCategory
}
// 引用结构体的嵌入字段
func (a Animal) Category() string{
// 通过 a.AnimalCategory 选择了 a 的嵌入字段
// 然后又选择了该字段的 String 方法并调用了它
return a.AnimalCategory.String()
}
func main(){
category := AnimalCategory{species: "cat"}
animal := Animal {
scientificName: "American Shorthair",
AnimalCategory: category,
}
// 嵌入字段 AnimalCategory 的 String 方法会被当作 Animal 的方法用
fmt.Printf("The animal: %s\n", animal)
}
屏蔽嵌入字段中的同名的方法:
package main
import (
"fmt"
)
type AnimalCategory struct {
kingdom string // 界
phylum string // 门
class string // 纲
order string // 目
family string // 科
genus string // 属
species string // 种
}
// String 方法隶属于 AnimalCategory 类型
// String 的功能是提供当前值的字符串表示形式
func (ac AnimalCategory) String() string {
return fmt.Sprintf("%s%s%s%s%s%s%s",
ac.kingdom, ac.phylum, ac.class, ac.order,
ac.family, ac.genus, ac.species)
}
type Animal struct {
scientificName string // 学名
// 只有类型名,是嵌入字段
// 嵌入字段的方法会被无条件整合到被嵌入类型的方法集中
AnimalCategory
}
// 引用结构体的嵌入字段
func (a Animal) Category() string{
// 通过 a.AnimalCategory 选择了 a 的嵌入字段
// 然后又选择了该字段的 String 方法并调用了它
return a.AnimalCategory.String()
}
type Cat struct {
name string
Animal
}
// 该方法会屏蔽嵌入字段中的同名方法,只要名称相同即可
func (cat Cat) String() string {
return fmt.Sprintf("%s (category: %s, name: %q)",
cat.scientificName, cat.Animal.AnimalCategory, cat.name)
}
func main(){
category := AnimalCategory{species: "cat"}
animal := Animal {
scientificName: "American Shorthair",
AnimalCategory: category,
}
cat := Cat {
name: "little cat",
Animal: animal,
}
fmt.Printf("The cat: %s\n", cat)
}
指针方法和值方法
package main
import (
"fmt"
)
type Cat struct {
name string
}
// 指针方法
func (cat *Cat) SetName(name string) {
cat.name = name
}
// 值方法
func(cat Cat) SetNameOfCopy(name string) {
cat.name = name
}
func (cat Cat) String() string {
return fmt.Sprintf("%s", cat.name)
}
func main(){
cat := Cat {
name: "cat",
}
fmt.Printf("The cat: %s\n", cat)
cat.SetName("cat1") // 指针方法
fmt.Printf("The cat: %s\n", cat)
cat.SetNameOfCopy("cat2") // 值方法
fmt.Printf("The cat: %s\n", cat)
type Pet interface {
SetName(name string)
}
// 一个自定义数据类型的方法集合中仅会包含它的所有值方法
// 而该类型的指针类型的方法集合却囊括了所有方法,包括值方法和指针方法
_, ok := interface{}(cat).(Pet) // 无法转换,因为不能实现指针方法
fmt.Printf("Cat implements interface Pet: %v\n", ok)
_, ok = interface{}(&cat).(Pet) // 可以转换
fmt.Printf("Cat implements interface Pet: %v\n", ok)
}