📜  Golang 中的组合

📅  最后修改于: 2021-10-25 02:50:45             🧑  作者: Mango

组合是一种用于编写可重用代码段的方法。当对象由具有特定行为的其他较小对象组成时就可以实现,换句话说,具有更广泛功能的较大对象嵌入具有特定行为的较小对象。组合的最终目标与继承相同,但是,在这方面,更大的对象不是从父类/对象继承特性,而是由其他对象组成,从而可以使用它们的功能。

由于在 Go 语言中编写有效的代码主要围绕使用结构和接口,因此组合是该语言必须提供的内容的关键。在本文中,我们将通过类型嵌入讨论使用类型与结构和接口的组合:

示例 1:结构的组合

// Golang program to store information
// about games in structs and display them
package main
  
import "fmt"
  
// We create a struct details to hold
// generic information about games
type details struct {
    genre       string
    genreRating string
    reviews     string
}
  
// We create a struct game to hold
// more specific information about
// a particular game
type game struct {
  
    name  string
    price string
    // We use composition through
    // embedding to add the
    // fields of the details 
    // struct to the game struct
    details
}
  
// this is a method defined
// on the details struct
func (d details) showDetails() {
    fmt.Println("Genre:", d.genre)
    fmt.Println("Genre Rating:", d.genreRating)
    fmt.Println("Reviews:", d.reviews)
}
  
// this is a method defined 
// on the game struct
// this method has access 
// to showDetails() as well since
// the game struct is composed
// of the details struct
func (g game) show() {
    fmt.Println("Name: ", g.name)
    fmt.Println("Price:", g.price)
    g.showDetails()
}
  
func main() {
  
    // defining a struct 
    // object of Type details
    action := details{"Action","18+", "mostly positive"}
      
    // defining a struct
    // object of Type game
    newGame := game{"XYZ","$125", action}
  
    newGame.show()
}

输出:

Name:  XYZ
Price: $125
Genre: Action
Genre Rating: 18+
Reviews: mostly positive

说明:在上面的代码片段中,我们创建了两个结构体: detailsgame 。结构详细信息包括有关游戏的通用信息。结构体游戏是一个复合结构体,它有自己的领域和细节领域。这种组合是通过类型嵌入实现的,因此第一个结构体变成了一段可重用的代码。

有趣的是,在 struct details上定义的方法可以被 type game 的对象访问,因为game是由details组成的。

示例 2:通过嵌入接口进行组合

在 Go 语言中,接口是隐式实现的。也就是说,如果在接口中定义的方法用于诸如结构之类的对象,则称该结构实现了该接口。一个接口可以嵌入其他接口以形成复合接口。如果复合接口中的所有接口都实现了,那么复合接口也被认为是由该对象实现的。

// Golang Program to implement composite interfaces
package main
  
import "fmt"
  
type purchase interface {
    sell()
}
  
type display interface {
    show()
}
  
// We use the two previous
// interfaces to form
// The following composite 
// interface through embedding
type salesman interface {
    purchase
    display
}
  
type game struct {
    name, price    string
    gameCollection []string
}
  
// We use the game struct to
// implement the interfaces
func (t game) sell() {
    fmt.Println("--------------------------------------")
    fmt.Println("Name:", t.name)
    fmt.Println("Price:", t.price)
    fmt.Println("--------------------------------------")
}
func (t game) show() {
    fmt.Println("The Games available are: ")
    for _, name := range t.gameCollection {
        fmt.Println(name)
    }
    fmt.Println("--------------------------------------")
}
   
// This method takes the composite
// interface as a parameter
// Since the interface is composed
// of purchase and display
// Hence the child methods of those
// interfaces can be accessed here
func shop(s salesman) {
    fmt.Println(s)
    s.sell()
    s.show()
}
  
func main() {
  
    collection := []string{"XYZ", 
        "Trial by Code", "Sea of Rubies"}
    game1 := game{"ABC", "$125", collection}
    shop(game1)
  
}

输出:

{ABC $125 [XYZ Trial by Code Sea of Rubies]}
--------------------------------------
Name: ABC
Price: $125
--------------------------------------
The Games available are: 
XYZ
Trial by Code
Sea of Rubies
--------------------------------------

说明:首先,我们创建了 2 个接口购买展示,它们有自己的方法原型。然后我们将它们嵌入到接口销售员中,以形成一个复合结构。这演示了 Go Lang 中组合概念的使用。在 shop() 方法中,我们通过在方法中传递 Type game 对象来实现销售员接口。由于这个方法实现了复合接口,我们可以访问我们最初声明的两个接口的子方法。这样,可以通过干净的可重用代码进行有效的 go 编程。