章工运维 章工运维
首页
  • linux
  • windows
  • 中间件
  • 监控
  • 网络
  • 存储
  • 安全
  • 防火墙
  • 数据库
  • 系统
  • docker
  • 运维工具
  • other
  • elk
  • K8S
  • ansible
  • Jenkins
  • GitLabCI_CD
  • 随笔
  • 面试
  • 工具
  • 收藏夹
  • Shell
  • python
  • golang
友链
  • 索引

    • 分类
    • 标签
    • 归档
    • 首页 (opens new window)
    • 关于我 (opens new window)
    • 图床 (opens new window)
    • 评论 (opens new window)
    • 导航栏 (opens new window)
周刊
GitHub (opens new window)

章工运维

业精于勤,荒于嬉
首页
  • linux
  • windows
  • 中间件
  • 监控
  • 网络
  • 存储
  • 安全
  • 防火墙
  • 数据库
  • 系统
  • docker
  • 运维工具
  • other
  • elk
  • K8S
  • ansible
  • Jenkins
  • GitLabCI_CD
  • 随笔
  • 面试
  • 工具
  • 收藏夹
  • Shell
  • python
  • golang
友链
  • 索引

    • 分类
    • 标签
    • 归档
    • 首页 (opens new window)
    • 关于我 (opens new window)
    • 图床 (opens new window)
    • 评论 (opens new window)
    • 导航栏 (opens new window)
周刊
GitHub (opens new window)
  • python

  • shell

  • go

    • go基础

      • 指针
      • 数组
      • 切片
      • 字典
      • 结构体
      • 匿名组合
      • 方法
        • 接口
        • error接口
        • panic使用
      • Init函数和main函数
      • 下划线
      • go报错问题收集
      • Redis和MySQL结合的Web服务示例
      • go定义json数据
      • 使用go和vue编写学生管理系统
      • gin框架探索
    • 编程
    • go
    • go基础
    章工运维
    2024-11-14
    目录

    方法

    在Go语言中,方法组合是指通过结构体的匿名组合使一个结构体能够调用其他结构体的方法。方法组合使代码复用更加方便,同时也可以通过不同组合实现多样化的功能。

    Go的“方法组合”与“匿名组合”密切相关。一个结构体可以匿名嵌入其他结构体,从而直接继承和调用被嵌入结构体的方法。使用这种方式,可以创建模块化的代码结构,并在需要时模拟某种多重继承的效果。

    # 1. 方法组合的基本概念

    在Go中,当一个结构体A匿名组合了另一个结构体B时,A不仅可以直接访问B的字段,还可以直接调用B的方法,就像这些方法属于A一样。这种方式被称为方法组合。

    例如,如果我们有一个基础Person结构体定义了Greet方法,那么在其他结构体(如Employee)中匿名组合Person后,Employee也可以直接使用Greet方法。

    # 2. 方法组合示例

    # 2.1 定义基础结构体和方法

    首先,我们定义一个基础的Person结构体和它的Greet方法:

    package main
    
    import "fmt"
    
    type Person struct {
        Name string
        Age  int
    }
    
    func (p Person) Greet() {
        fmt.Printf("Hello, my name is %s and I am %d years old.\n", p.Name, p.Age)
    }
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12

    # 2.2 使用方法组合

    接下来定义一个新的结构体Employee,它匿名组合了Person结构体,从而可以直接使用Person的Greet方法。

    type Employee struct {
        Person
        EmployeeID int
    }
    
    func main() {
        e := Employee{
            Person:     Person{Name: "Alice", Age: 30},
            EmployeeID: 101,
        }
    
        // 使用组合的Greet方法
        e.Greet() // 输出: Hello, my name is Alice and I am 30 years old.
    }
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14

    在这个例子中,Employee结构体组合了Person,所以我们可以直接通过e.Greet()调用Person的Greet方法。

    # 3. 方法组合中的指针接收器方法

    如果被组合的结构体中的方法使用了指针接收器,组合后的结构体也可以调用这些方法。

    func (p *Person) HaveBirthday() {
        p.Age++
        fmt.Printf("%s just had a birthday and is now %d years old.\n", p.Name, p.Age)
    }
    
    func main() {
        e := Employee{
            Person:     Person{Name: "Bob", Age: 40},
            EmployeeID: 102,
        }
    
        // 使用组合的指针接收器方法
        e.HaveBirthday() // 输出: Bob just had a birthday and is now 41 years old.
    }
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14

    这里HaveBirthday方法使用了指针接收器,在Employee中可以直接使用该方法,这样可以修改Person的Age字段。

    # 4. 多重方法组合

    Go支持多重匿名组合,通过组合多个结构体,可以实现不同功能模块的组合使用。

    type Address struct {
        City   string
        Street string
    }
    
    type Contact struct {
        Phone string
        Email string
    }
    
    type Person struct {
        Name    string
        Age     int
        Address // 匿名组合Address
        Contact // 匿名组合Contact
    }
    
    func (a Address) PrintAddress() {
        fmt.Printf("Address: %s, %s\n", a.Street, a.City)
    }
    
    func (c Contact) PrintContact() {
        fmt.Printf("Contact: Phone=%s, Email=%s\n", c.Phone, c.Email)
    }
    
    func main() {
        p := Person{
            Name:    "Charlie",
            Age:     35,
            Address: Address{City: "New York", Street: "5th Ave"},
            Contact: Contact{Phone: "123-456-7890", Email: "charlie@example.com"},
        }
    
        // 调用组合的方法
        p.PrintAddress() // 输出: Address: 5th Ave, New York
        p.PrintContact() // 输出: Contact: Phone=123-456-7890, Email=charlie@example.com
    }
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37

    在这个例子中,Person结构体匿名组合了Address和Contact结构体,所以可以直接调用PrintAddress和PrintContact方法。

    # 5. 方法组合的实际应用案例

    # 5.1 角色权限管理

    假设我们要构建一个角色管理系统,其中Admin和User共享一些基本的Person信息和功能,通过方法组合可以复用这些信息和功能。

    type Person struct {
        Name string
        Age  int
    }
    
    func (p Person) ShowInfo() {
        fmt.Printf("Name: %s, Age: %d\n", p.Name, p.Age)
    }
    
    type Admin struct {
        Person
        Permissions []string
    }
    
    func (a Admin) ShowPermissions() {
        fmt.Printf("Permissions: %v\n", a.Permissions)
    }
    
    type User struct {
        Person
        MembershipLevel string
    }
    
    func (u User) ShowMembership() {
        fmt.Printf("Membership Level: %s\n", u.MembershipLevel)
    }
    
    func main() {
        admin := Admin{
            Person:      Person{Name: "Alice", Age: 30},
            Permissions: []string{"Read", "Write", "Execute"},
        }
        user := User{
            Person:         Person{Name: "Bob", Age: 25},
            MembershipLevel: "Gold",
        }
    
        admin.ShowInfo()         // 输出: Name: Alice, Age: 30
        admin.ShowPermissions()   // 输出: Permissions: [Read Write Execute]
    
        user.ShowInfo()           // 输出: Name: Bob, Age: 25
        user.ShowMembership()     // 输出: Membership Level: Gold
    }
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43

    # 5.2 服务组合

    假设我们在构建一个网络服务系统,其中AuthService和LogService都需要访问Service的基本功能,可以通过组合来实现。

    type Service struct {
        Name string
    }
    
    func (s Service) Start() {
        fmt.Printf("Service %s is starting...\n", s.Name)
    }
    
    type AuthService struct {
        Service
    }
    
    func (a AuthService) Authenticate(user string) {
        fmt.Printf("Authenticating user: %s\n", user)
    }
    
    type LogService struct {
        Service
    }
    
    func (l LogService) LogEvent(event string) {
        fmt.Printf("Logging event: %s\n", event)
    }
    
    func main() {
        auth := AuthService{
            Service: Service{Name: "Authentication"},
        }
        log := LogService{
            Service: Service{Name: "Logger"},
        }
    
        auth.Start()          // 输出: Service Authentication is starting...
        auth.Authenticate("Alice") // 输出: Authenticating user: Alice
    
        log.Start()           // 输出: Service Logger is starting...
        log.LogEvent("User Login") // 输出: Logging event: User Login
    }
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38

    # 总结

    • 方法组合是Go语言中一种灵活的代码复用方式,通过匿名组合让结构体能够直接访问其他结构体的方法。
    • 多重匿名组合可以构建更复杂的结构体,并复用多个结构体的方法,实现类似“多重继承”的效果。
    • 方法组合在系统设计中十分有用,例如构建多角色系统、服务组合等。
    微信 支付宝
    上次更新: 2024/11/21, 10:50:23

    ← 匿名组合 接口→

    最近更新
    01
    shell脚本模块集合
    05-13
    02
    生活小技巧(认知版)
    04-29
    03
    生活小技巧(防骗版)
    04-29
    更多文章>
    Theme by Vdoing | Copyright © 2019-2025 | 点击查看十年之约 | 鄂ICP备2024072800号
    • 跟随系统
    • 浅色模式
    • 深色模式
    • 阅读模式