1000 words
5 minutes
Go语言教程:深入探究结构体、方法和接口
介绍
在Go语言中,结构体(struct)、方法和接口是构建复杂数据模型和实现多态行为的基础。本文将通过一个具体的代码示例,深入探究这些概念,并展示如何举一反三地应用它们。
示例代码
以下是一个完整的Go语言代码示例,展示了如何定义结构体、方法以及接口:
package main
import "fmt"
type Cat struct {
name string // 名字。
scientificName string // 学名。
category string // 动物学基本分类。
}
func New(name, scientificName, category string) Cat {
return Cat{
name: name,
scientificName: scientificName,
category: category,
}
}
func (cat *Cat) SetName(name string) {
cat.name = name
}
func (cat Cat) SetNameOfCopy(name string) {
cat.name = name
}
func (cat Cat) Name() string {
return cat.name
}
func (cat Cat) ScientificName() string {
return cat.scientificName
}
func (cat Cat) Category() string {
return cat.category
}
func (cat Cat) String() string {
return fmt.Sprintf("%s (category: %s, name: %q)",
cat.scientificName, cat.category, cat.name)
}
func main() {
cat := New("little pig", "American Shorthair", "cat")
cat.SetName("monster") // (&cat).SetName("monster")
fmt.Printf("The cat: %s\\n", cat)
cat.SetNameOfCopy("little pig")
fmt.Printf("The cat: %s\\n", cat)
type Pet interface {
SetName(name string)
Name() string
Category() string
ScientificName() 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)
}
代码解析
定义结构体
首先,我们定义了一个 Cat
结构体,用于表示猫的基本信息,包括名字、学名和分类。
type Cat struct {
name string // 名字。
scientificName string // 学名。
category string // 动物学基本分类。
}
构造函数
接下来,我们定义了一个构造函数 New
,用于创建 Cat
结构体的实例。
func New(name, scientificName, category string) Cat {
return Cat{
name: name,
scientificName: scientificName,
category: category,
}
}
方法定义
我们为 Cat
结构体定义了一些方法,包括设置名字、获取名字、获取学名和获取分类的方法。
func (cat *Cat) SetName(name string) {
cat.name = name
}
func (cat Cat) SetNameOfCopy(name string) {
cat.name = name
}
func (cat Cat) Name() string {
return cat.name
}
func (cat Cat) ScientificName() string {
return cat.scientificName
}
func (cat Cat) Category() string {
return cat.category
}
func (cat Cat) String() string {
return fmt.Sprintf("%s (category: %s, name: %q)",
cat.scientificName, cat.category, cat.name)
}
需要注意的是,SetName
方法接收一个指向 Cat
结构体的指针,这意味着它可以修改原始结构体的内容。而 SetNameOfCopy
方法接收的是结构体的值,这意味着它只能修改副本的内容,不会影响原始结构体。
主函数
在 main
函数中,我们创建了一个 Cat
实例,并调用了不同的方法来展示其行为。
func main() {
cat := New("little pig", "American Shorthair", "cat")
cat.SetName("monster") // (&cat).SetName("monster")
fmt.Printf("The cat: %s\\n", cat)
cat.SetNameOfCopy("little pig")
fmt.Printf("The cat: %s\\n", cat)
接口实现
我们定义了一个 Pet
接口,并检查 Cat
结构体和 *Cat
指针是否实现了该接口。
type Pet interface {
SetName(name string)
Name() string
Category() string
ScientificName() 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)
运行结果
运行上述代码,输出结果如下:
The cat: American Shorthair (category: cat, name: "monster")
The cat: American Shorthair (category: cat, name: "monster")
Cat implements interface Pet: false
*Cat implements interface Pet: true
举一反三
通过这个示例,我们可以举一反三地应用这些概念。例如,我们可以定义一个 Dog
结构体,并实现类似的方法和接口:
type Dog struct {
name string
scientificName string
category string
}
func NewDog(name, scientificName, category string) Dog {
return Dog{
name: name,
scientificName: scientificName,
category: category,
}
}
func (dog *Dog) SetName(name string) {
dog.name = name
}
func (dog Dog) Name() string {
return dog.name
}
func (dog Dog) ScientificName() string {
return dog.scientificName
}
func (dog Dog) Category() string {
return dog.category
}
func (dog Dog) String() string {
return fmt.Sprintf("%s (category: %s, name: %q)",
dog.scientificName, dog.category, dog.name)
}
然后,我们可以在 main
函数中创建 Dog
实例,并检查其行为:
func main() {
dog := NewDog("buddy", "Canis lupus familiaris", "dog")
dog.SetName("max")
fmt.Printf("The dog: %s\\n", dog)
type Pet interface {
SetName(name string)
Name() string
Category() string
ScientificName() string
}
_, 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)
}
总结
通过这个教程,我们深入探讨了Go语言中的结构体、方法和接口,并展示了如何举一反三地应用这些概念。理解这些基础知识将帮助你在Go语言中构建更复杂和灵活的程序。
Go语言教程:深入探究结构体、方法和接口
https://blog.ithuo.net/posts/go-tutorial-struct-method-interface/