1.4.4 结构体高级特性 #
在掌握了结构体的基础知识后,本节将深入探讨 Go 语言结构体的高级特性。这些特性包括方法定义、接收者类型、结构体嵌入的深层应用、接口实现等。这些高级特性是实现面向对象编程和构建复杂系统的重要工具。
方法定义 #
方法的基本概念 #
方法是与特定类型关联的函数。在 Go 语言中,可以为任何自定义类型定义方法,包括结构体。方法通过接收者(receiver)与类型关联。
值接收者方法 #
package main
import (
"fmt"
"math"
)
type Circle struct {
Radius float64
}
type Rectangle struct {
Width, Height float64
}
// 值接收者方法
func (c Circle) Area() float64 {
return math.Pi * c.Radius * c.Radius
}
func (c Circle) Circumference() float64 {
return 2 * math.Pi * c.Radius
}
func (r Rectangle) Area() float64 {
return r.Width * r.Height
}
func (r Rectangle) Perimeter() float64 {
return 2 * (r.Width + r.Height)
}
// 方法可以调用其他方法
func (c Circle) String() string {
return fmt.Sprintf("圆形(半径: %.2f, 面积: %.2f)", c.Radius, c.Area())
}
func (r Rectangle) String() string {
return fmt.Sprintf("矩形(宽: %.2f, 高: %.2f, 面积: %.2f)",
r.Width, r.Height, r.Area())
}
func main() {
circle := Circle{Radius: 5.0}
rectangle := Rectangle{Width: 4.0, Height: 6.0}
fmt.Printf("圆形面积: %.2f\n", circle.Area())
fmt.Printf("圆形周长: %.2f\n", circle.Circumference())
fmt.Printf("矩形面积: %.2f\n", rectangle.Area())
fmt.Printf("矩形周长: %.2f\n", rectangle.Perimeter())
fmt.Println(circle.String())
fmt.Println(rectangle.String())
}
指针接收者方法 #
package main
import "fmt"
type BankAccount struct {
Owner string
Balance float64
}
// 指针接收者方法 - 可以修改结构体
func (account *BankAccount) Deposit(amount float64) {
if amount > 0 {
account.Balance += amount
fmt.Printf("存入 %.2f,当前余额: %.2f\n", amount, account.Balance)
}
}
func (account *BankAccount) Withdraw(amount float64) bool {
if amount > 0 && amount <= account.Balance {
account.Balance -= amount
fmt.Printf("取出 %.2f,当前余额: %.2f\n", amount, account.Balance)
return true
}
fmt.Printf("取款失败,余额不足或金额无效\n")
return false
}
// 值接收者方法 - 只读操作
func (account BankAccount) GetBalance() float64 {
return account.Balance
}
func (account BankAccount) GetOwner() string {
return account.Owner
}
// 指针接收者方法 - 修改所有者信息
func (account *BankAccount) ChangeOwner(newOwner string) {
oldOwner := account.Owner
account.Owner = newOwner
fmt.Printf("账户所有者从 %s 变更为 %s\n", oldOwner, newOwner)
}
func main() {
account := BankAccount{
Owner: "张三",
Balance: 1000.0,
}
fmt.Printf("初始账户: %s, 余额: %.2f\n", account.GetOwner(), account.GetBalance())
account.Deposit(500.0)
account.Withdraw(200.0)
account.Withdraw(2000.0) // 余额不足
account.ChangeOwner("李四")
fmt.Printf("最终账户: %s, 余额: %.2f\n", account.GetOwner(), account.GetBalance())
}
方法集和接收者类型选择 #
package main
import "fmt"
type Counter struct {
value int
}
// 值接收者方法
func (c Counter) Value() int {
return c.value
}
// 指针接收者方法
func (c *Counter) Increment() {
c.value++
}
func (c *Counter) Decrement() {
c.value--
}
func (c *Counter) Reset() {
c.value = 0
}
// 演示方法集的概念
func demonstrateMethodSet() {
fmt.Println("=== 方法集演示 ===")
// 值类型变量
var counter1 Counter
counter1.Increment() // Go 自动转换为 (&counter1).Increment()
fmt.Printf("counter1 值: %d\n", counter1.Value())
// 指针类型变量
counter2 := &Counter{}
counter2.Increment()
counter2.Increment()
fmt.Printf("counter2 值: %d\n", counter2.Value()) // Go 自动解引用
// 方法集规则:
// - 值类型可以调用值接收者和指针接收者方法
// - 指针类型可以调用值接收者和指针接收者方法
}
func main() {
demonstrateMethodSet()
counter := Counter{value: 10}
fmt.Printf("初始值: %d\n", counter.Value())
counter.Increment()
counter.Increment()
fmt.Printf("增加后: %d\n", counter.Value())
counter.Decrement()
fmt.Printf("减少后: %d\n", counter.Value())
counter.Reset()
fmt.Printf("重置后: %d\n", counter.Value())
}
结构体嵌入的高级应用 #
方法提升 #
package main
import "fmt"
type Engine struct {
Power int
FuelType string
IsRunning bool
}
func (e *Engine) Start() {
if !e.IsRunning {
e.IsRunning = true
fmt.Printf("引擎启动 (功率: %d, 燃料: %s)\n", e.Power, e.FuelType)
}
}
func (e *Engine) Stop() {
if e.IsRunning {
e.IsRunning = false
fmt.Println("引擎停止")
}
}
func (e Engine) Status() string {
if e.IsRunning {
return "运行中"
}
return "已停止"
}
type GPS struct {
Latitude float64
Longitude float64
}
func (g *GPS) UpdateLocation(lat, lng float64) {
g.Latitude = lat
g.Longitude = lng
fmt.Printf("位置更新: (%.6f, %.6f)\n", lat, lng)
}
func (g GPS) GetLocation() (float64, float64) {
return g.Latitude, g.Longitude
}
type Car struct {
Brand string
Model string
Year int
Engine // 嵌入引擎
GPS // 嵌入GPS
}
// Car 的专有方法
func (c *Car) Drive() {
if !c.Engine.IsRunning {
fmt.Println("请先启动引擎")
return
}
fmt.Printf("%s %s 正在行驶\n", c.Brand, c.Model)
}
func (c Car) Info() string {
return fmt.Sprintf("%d年 %s %s", c.Year, c.Brand, c.Model)
}
func main() {
car := Car{
Brand: "Toyota",
Model: "Camry",
Year: 2023,
Engine: Engine{
Power: 200,
FuelType: "汽油",
},
GPS: GPS{
Latitude: 39.9042,
Longitude: 116.4074,
},
}
fmt.Println("车辆信息:", car.Info())
// 调用嵌入类型的方法(方法提升)
fmt.Printf("引擎状态: %s\n", car.Status()) // 调用 Engine.Status()
car.Start() // 调用 Engine.Start()
car.Drive()
lat, lng := car.GetLocation() // 调用 GPS.GetLocation()
fmt.Printf("当前位置: (%.6f, %.6f)\n", lat, lng)
car.UpdateLocation(40.7128, -74.0060) // 调用 GPS.UpdateLocation()
car.Stop() // 调用 Engine.Stop()
}
嵌入冲突和解决 #
package main
import "fmt"
type A struct {
Name string
}
func (a A) Method() string {
return "A的方法"
}
func (a A) CommonMethod() string {
return "A的通用方法"
}
type B struct {
Name string
}
func (b B) Method() string {
return "B的方法"
}
func (b B) CommonMethod() string {
return "B的通用方法"
}
type C struct {
A
B
Value int
}
// C 的专有方法
func (c C) CMethod() string {
return "C的专有方法"
}
// 解决方法冲突
func (c C) ResolveConflict() {
fmt.Println("解决嵌入冲突:")
fmt.Printf("A.Method(): %s\n", c.A.Method())
fmt.Printf("B.Method(): %s\n", c.B.Method())
fmt.Printf("A.CommonMethod(): %s\n", c.A.CommonMethod())
fmt.Printf("B.CommonMethod(): %s\n", c.B.CommonMethod())
}
// 多层嵌入示例
type Inner struct {
InnerValue int
}
func (i Inner) InnerMethod() string {
return fmt.Sprintf("内层方法,值: %d", i.InnerValue)
}
type Middle struct {
Inner
MiddleValue string
}
func (m Middle) MiddleMethod() string {
return fmt.Sprintf("中层方法,值: %s", m.MiddleValue)
}
type Outer struct {
Middle
OuterValue bool
}
func (o Outer) OuterMethod() string {
return fmt.Sprintf("外层方法,值: %t", o.OuterValue)
}
func main() {
c := C{
A: A{Name: "A结构体"},
B: B{Name: "B结构体"},
Value: 42,
}
// 访问嵌入字段
fmt.Printf("A.Name: %s\n", c.A.Name)
fmt.Printf("B.Name: %s\n", c.B.Name)
// 方法冲突需要显式指定
// fmt.Println(c.Method()) // 编译错误:模糊调用
// fmt.Println(c.CommonMethod()) // 编译错误:模糊调用
c.ResolveConflict()
fmt.Printf("C的专有方法: %s\n", c.CMethod())
// 多层嵌入示例
fmt.Println("\n=== 多层嵌入示例 ===")
outer := Outer{
Middle: Middle{
Inner: Inner{InnerValue: 100},
MiddleValue: "中层数据",
},
OuterValue: true,
}
// 可以直接调用各层的方法
fmt.Println(outer.InnerMethod()) // 方法提升
fmt.Println(outer.MiddleMethod())
fmt.Println(outer.OuterMethod())
// 也可以通过完整路径访问
fmt.Printf("内层值: %d\n", outer.Middle.Inner.InnerValue)
}
接口实现 #
隐式接口实现 #
package main
import (
"fmt"
"math"
)
// 定义接口
type Shape interface {
Area() float64
Perimeter() float64
}
type Drawable interface {
Draw()
}
// 组合接口
type DrawableShape interface {
Shape
Drawable
}
// 实现 Shape 接口的结构体
type Circle struct {
Radius float64
}
func (c Circle) Area() float64 {
return math.Pi * c.Radius * c.Radius
}
func (c Circle) Perimeter() float64 {
return 2 * math.Pi * c.Radius
}
func (c Circle) Draw() {
fmt.Printf("绘制圆形,半径: %.2f\n", c.Radius)
}
type Rectangle struct {
Width, Height float64
}
func (r Rectangle) Area() float64 {
return r.Width * r.Height
}
func (r Rectangle) Perimeter() float64 {
return 2 * (r.Width + r.Height)
}
func (r Rectangle) Draw() {
fmt.Printf("绘制矩形,宽: %.2f, 高: %.2f\n", r.Width, r.Height)
}
type Triangle struct {
Base, Height, Side1, Side2 float64
}
func (t Triangle) Area() float64 {
return 0.5 * t.Base * t.Height
}
func (t Triangle) Perimeter() float64 {
return t.Base + t.Side1 + t.Side2
}
func (t Triangle) Draw() {
fmt.Printf("绘制三角形,底: %.2f, 高: %.2f\n", t.Base, t.Height)
}
// 使用接口的函数
func printShapeInfo(s Shape) {
fmt.Printf("面积: %.2f, 周长: %.2f\n", s.Area(), s.Perimeter())
}
func drawShape(d Drawable) {
d.Draw()
}
func processDrawableShape(ds DrawableShape) {
ds.Draw()
fmt.Printf("面积: %.2f, 周长: %.2f\n", ds.Area(), ds.Perimeter())
}
func main() {
shapes := []Shape{
Circle{Radius: 5.0},
Rectangle{Width: 4.0, Height: 6.0},
Triangle{Base: 3.0, Height: 4.0, Side1: 3.0, Side2: 5.0},
}
fmt.Println("=== 形状信息 ===")
for i, shape := range shapes {
fmt.Printf("形状 %d: ", i+1)
printShapeInfo(shape)
}
fmt.Println("\n=== 绘制形状 ===")
for _, shape := range shapes {
if drawable, ok := shape.(Drawable); ok {
drawShape(drawable)
}
}
fmt.Println("\n=== 处理可绘制形状 ===")
circle := Circle{Radius: 3.0}
processDrawableShape(circle)
}
类型断言和类型开关 #
package main
import "fmt"
type Animal interface {
Speak() string
Move() string
}
type Dog struct {
Name string
Breed string
}
func (d Dog) Speak() string {
return "汪汪"
}
func (d Dog) Move() string {
return "跑步"
}
func (d Dog) Fetch() string {
return fmt.Sprintf("%s 正在捡球", d.Name)
}
type Cat struct {
Name string
Color string
}
func (c Cat) Speak() string {
return "喵喵"
}
func (c Cat) Move() string {
return "悄悄走"
}
func (c Cat) Climb() string {
return fmt.Sprintf("%s 正在爬树", c.Name)
}
type Bird struct {
Name string
CanFly bool
}
func (b Bird) Speak() string {
return "啾啾"
}
func (b Bird) Move() string {
if b.CanFly {
return "飞行"
}
return "跳跃"
}
func (b Bird) Fly() string {
if b.CanFly {
return fmt.Sprintf("%s 正在飞行", b.Name)
}
return fmt.Sprintf("%s 不会飞", b.Name)
}
// 类型断言示例
func handleAnimal(animal Animal) {
fmt.Printf("动物叫声: %s, 移动方式: %s\n", animal.Speak(), animal.Move())
// 类型断言
if dog, ok := animal.(Dog); ok {
fmt.Printf("这是一只狗: %s (%s)\n", dog.Name, dog.Breed)
fmt.Println(dog.Fetch())
}
if cat, ok := animal.(Cat); ok {
fmt.Printf("这是一只猫: %s (%s)\n", cat.Name, cat.Color)
fmt.Println(cat.Climb())
}
if bird, ok := animal.(Bird); ok {
fmt.Printf("这是一只鸟: %s\n", bird.Name)
fmt.Println(bird.Fly())
}
}
// 类型开关示例
func identifyAnimal(animal Animal) {
switch v := animal.(type) {
case Dog:
fmt.Printf("狗狗 %s,品种: %s\n", v.Name, v.Breed)
fmt.Println("特殊技能:", v.Fetch())
case Cat:
fmt.Printf("猫咪 %s,颜色: %s\n", v.Name, v.Color)
fmt.Println("特殊技能:", v.Climb())
case Bird:
fmt.Printf("鸟儿 %s,会飞: %t\n", v.Name, v.CanFly)
fmt.Println("特殊技能:", v.Fly())
default:
fmt.Printf("未知动物类型: %T\n", v)
}
}
func main() {
animals := []Animal{
Dog{Name: "旺财", Breed: "金毛"},
Cat{Name: "咪咪", Color: "橘色"},
Bird{Name: "小黄", CanFly: true},
Bird{Name: "企鹅", CanFly: false},
}
fmt.Println("=== 类型断言处理 ===")
for i, animal := range animals {
fmt.Printf("\n动物 %d:\n", i+1)
handleAnimal(animal)
}
fmt.Println("\n=== 类型开关处理 ===")
for i, animal := range animals {
fmt.Printf("\n动物 %d: ", i+1)
identifyAnimal(animal)
}
}
结构体的高级模式 #
构造函数模式 #
package main
import (
"fmt"
"time"
)
type User struct {
id int
username string
email string
createdAt time.Time
isActive bool
}
// 构造函数
func NewUser(username, email string) *User {
return &User{
id: generateID(),
username: username,
email: email,
createdAt: time.Now(),
isActive: true,
}
}
// 带验证的构造函数
func NewUserWithValidation(username, email string) (*User, error) {
if username == "" {
return nil, fmt.Errorf("用户名不能为空")
}
if email == "" {
return nil, fmt.Errorf("邮箱不能为空")
}
if !isValidEmail(email) {
return nil, fmt.Errorf("邮箱格式无效")
}
return &User{
id: generateID(),
username: username,
email: email,
createdAt: time.Now(),
isActive: true,
}, nil
}
// 选项模式构造函数
type UserOption func(*User)
func WithID(id int) UserOption {
return func(u *User) {
u.id = id
}
}
func WithCreatedAt(t time.Time) UserOption {
return func(u *User) {
u.createdAt = t
}
}
func WithInactive() UserOption {
return func(u *User) {
u.isActive = false
}
}
func NewUserWithOptions(username, email string, options ...UserOption) *User {
user := &User{
id: generateID(),
username: username,
email: email,
createdAt: time.Now(),
isActive: true,
}
for _, option := range options {
option(user)
}
return user
}
// 方法
func (u *User) GetID() int {
return u.id
}
func (u *User) GetUsername() string {
return u.username
}
func (u *User) GetEmail() string {
return u.email
}
func (u *User) IsActive() bool {
return u.isActive
}
func (u *User) Activate() {
u.isActive = true
}
func (u *User) Deactivate() {
u.isActive = false
}
func (u *User) String() string {
return fmt.Sprintf("User{ID: %d, Username: %s, Email: %s, Active: %t, Created: %s}",
u.id, u.username, u.email, u.isActive, u.createdAt.Format("2006-01-02 15:04:05"))
}
// 辅助函数
var idCounter = 0
func generateID() int {
idCounter++
return idCounter
}
func isValidEmail(email string) bool {
// 简单的邮箱验证
return len(email) > 0 && strings.Contains(email, "@")
}
func main() {
// 基本构造函数
user1 := NewUser("alice", "[email protected]")
fmt.Println("用户1:", user1)
// 带验证的构造函数
user2, err := NewUserWithValidation("bob", "[email protected]")
if err != nil {
fmt.Printf("创建用户失败: %v\n", err)
} else {
fmt.Println("用户2:", user2)
}
// 无效用户
_, err = NewUserWithValidation("", "invalid-email")
if err != nil {
fmt.Printf("预期的错误: %v\n", err)
}
// 选项模式
user3 := NewUserWithOptions(
"charlie",
"[email protected]",
WithID(1000),
WithCreatedAt(time.Date(2023, 1, 1, 0, 0, 0, 0, time.UTC)),
WithInactive(),
)
fmt.Println("用户3:", user3)
// 使用方法
user3.Activate()
fmt.Printf("激活后的用户3: %s\n", user3.GetUsername())
}
建造者模式 #
package main
import (
"fmt"
"strings"
)
type Database struct {
host string
port int
username string
password string
database string
options map[string]string
}
type DatabaseBuilder struct {
db *Database
}
func NewDatabaseBuilder() *DatabaseBuilder {
return &DatabaseBuilder{
db: &Database{
options: make(map[string]string),
},
}
}
func (b *DatabaseBuilder) Host(host string) *DatabaseBuilder {
b.db.host = host
return b
}
func (b *DatabaseBuilder) Port(port int) *DatabaseBuilder {
b.db.port = port
return b
}
func (b *DatabaseBuilder) Username(username string) *DatabaseBuilder {
b.db.username = username
return b
}
func (b *DatabaseBuilder) Password(password string) *DatabaseBuilder {
b.db.password = password
return b
}
func (b *DatabaseBuilder) DatabaseName(database string) *DatabaseBuilder {
b.db.database = database
return b
}
func (b *DatabaseBuilder) Option(key, value string) *DatabaseBuilder {
b.db.options[key] = value
return b
}
func (b *DatabaseBuilder) Build() (*Database, error) {
if b.db.host == "" {
return nil, fmt.Errorf("主机地址不能为空")
}
if b.db.port <= 0 {
return nil, fmt.Errorf("端口必须大于0")
}
if b.db.username == "" {
return nil, fmt.Errorf("用户名不能为空")
}
if b.db.database == "" {
return nil, fmt.Errorf("数据库名不能为空")
}
return b.db, nil
}
func (db *Database) ConnectionString() string {
var parts []string
parts = append(parts, fmt.Sprintf("host=%s", db.host))
parts = append(parts, fmt.Sprintf("port=%d", db.port))
parts = append(parts, fmt.Sprintf("user=%s", db.username))
parts = append(parts, fmt.Sprintf("dbname=%s", db.database))
if db.password != "" {
parts = append(parts, fmt.Sprintf("password=%s", db.password))
}
for key, value := range db.options {
parts = append(parts, fmt.Sprintf("%s=%s", key, value))
}
return strings.Join(parts, " ")
}
func (db *Database) String() string {
return fmt.Sprintf("Database{Host: %s, Port: %d, User: %s, DB: %s, Options: %v}",
db.host, db.port, db.username, db.database, db.options)
}
func main() {
// 使用建造者模式创建数据库配置
db, err := NewDatabaseBuilder().
Host("localhost").
Port(5432).
Username("admin").
Password("secret").
DatabaseName("myapp").
Option("sslmode", "disable").
Option("timezone", "UTC").
Build()
if err != nil {
fmt.Printf("构建数据库配置失败: %v\n", err)
return
}
fmt.Println("数据库配置:", db)
fmt.Println("连接字符串:", db.ConnectionString())
// 构建失败的例子
_, err = NewDatabaseBuilder().
Host("localhost").
// 缺少必要的配置
Build()
if err != nil {
fmt.Printf("预期的构建错误: %v\n", err)
}
}
单例模式 #
package main
import (
"fmt"
"sync"
)
type Logger struct {
level string
file string
}
var (
loggerInstance *Logger
loggerOnce sync.Once
)
func GetLogger() *Logger {
loggerOnce.Do(func() {
loggerInstance = &Logger{
level: "INFO",
file: "app.log",
}
fmt.Println("Logger 实例已创建")
})
return loggerInstance
}
func (l *Logger) SetLevel(level string) {
l.level = level
}
func (l *Logger) SetFile(file string) {
l.file = file
}
func (l *Logger) Log(message string) {
fmt.Printf("[%s] %s (写入到: %s)\n", l.level, message, l.file)
}
func (l *Logger) Info(message string) {
if l.level == "INFO" || l.level == "DEBUG" {
l.Log("INFO: " + message)
}
}
func (l *Logger) Error(message string) {
l.Log("ERROR: " + message)
}
// 配置管理单例
type Config struct {
settings map[string]string
mu sync.RWMutex
}
var (
configInstance *Config
configOnce sync.Once
)
func GetConfig() *Config {
configOnce.Do(func() {
configInstance = &Config{
settings: make(map[string]string),
}
// 加载默认配置
configInstance.settings["app_name"] = "MyApp"
configInstance.settings["version"] = "1.0.0"
fmt.Println("Config 实例已创建")
})
return configInstance
}
func (c *Config) Set(key, value string) {
c.mu.Lock()
defer c.mu.Unlock()
c.settings[key] = value
}
func (c *Config) Get(key string) (string, bool) {
c.mu.RLock()
defer c.mu.RUnlock()
value, exists := c.settings[key]
return value, exists
}
func (c *Config) GetAll() map[string]string {
c.mu.RLock()
defer c.mu.RUnlock()
result := make(map[string]string)
for k, v := range c.settings {
result[k] = v
}
return result
}
func main() {
// 测试 Logger 单例
logger1 := GetLogger()
logger2 := GetLogger()
fmt.Printf("logger1 == logger2: %t\n", logger1 == logger2)
logger1.Info("应用程序启动")
logger2.Error("发生错误")
logger1.SetLevel("DEBUG")
logger2.Info("调试信息") // 两个引用指向同一个实例
// 测试 Config 单例
config1 := GetConfig()
config2 := GetConfig()
fmt.Printf("config1 == config2: %t\n", config1 == config2)
config1.Set("database_url", "localhost:5432")
if url, exists := config2.Get("database_url"); exists {
fmt.Printf("数据库URL: %s\n", url)
}
fmt.Println("所有配置:")
for key, value := range config1.GetAll() {
fmt.Printf(" %s: %s\n", key, value)
}
// 并发测试
var wg sync.WaitGroup
for i := 0; i < 10; i++ {
wg.Add(1)
go func(id int) {
defer wg.Done()
logger := GetLogger()
logger.Info(fmt.Sprintf("来自 goroutine %d 的消息", id))
}(i)
}
wg.Wait()
}
小结 #
本节深入探讨了 Go 语言结构体的高级特性,主要内容包括:
方法定义 #
- 值接收者:适用于不需要修改结构体的方法
- 指针接收者:适用于需要修改结构体或避免复制的方法
- 方法集:理解值类型和指针类型的方法集规则
- 方法选择:根据需求选择合适的接收者类型
结构体嵌入 #
- 方法提升:嵌入类型的方法自动提升到外层类型
- 冲突解决:处理多个嵌入类型的方法和字段冲突
- 多层嵌入:支持任意层次的结构体嵌入
- 组合优于继承:Go 语言的组合设计哲学
接口实现 #
- 隐式实现:Go 语言的接口实现是隐式的
- 类型断言:运行时检查具体类型
- 类型开关:根据类型执行不同逻辑
- 接口组合:通过嵌入创建复合接口
设计模式 #
- 构造函数模式:提供多种创建对象的方式
- 选项模式:灵活的参数配置方法
- 建造者模式:逐步构建复杂对象
- 单例模式:确保全局唯一实例
最佳实践 #
- 根据是否需要修改状态选择接收者类型
- 使用接口提高代码的可测试性和可扩展性
- 通过嵌入实现代码复用
- 合理使用设计模式解决常见问题
这些高级特性是构建大型 Go 应用程序的重要工具,掌握它们有助于编写更加优雅、可维护的代码。
练习题:
- 实现一个图形绘制系统,支持多种图形类型和绘制方式
- 创建一个插件系统,使用接口实现可扩展的功能模块
- 设计一个配置管理系统,支持多种配置源和热重载
- 实现一个简单的 ORM 框架,使用结构体标签定义数据库映射
- 创建一个事件系统,支持事件的发布、订阅和处理