【问题标题】:Generic Method Parameters in GolangGolang 中的通用方法参数
【发布时间】:2015-02-08 10:59:42
【问题描述】:

我需要帮助才能使这项工作适用于任何类型。

我有一个函数需要接受具有ID 属性的其他类型。

我尝试过使用接口,但这不适用于我的 ID 属性案例。代码如下:

package main


import (
  "fmt"
  "strconv"
  )

type Mammal struct{
  ID int
  Name string 
}

type Human struct {  
  ID int
  Name string 
  HairColor string
}

func Count(ms []Mammal) *[]string { // How can i get this function to accept any type not just []Mammal
   IDs := make([]string, len(ms))
   for i, m := range ms {
     IDs[i] = strconv.Itoa(int(m.ID))
   }
   return &IDs
}

func main(){
  mammals := []Mammal{
    Mammal{1, "Carnivorious"},
    Mammal{2, "Ominivorious"},
  }

  humans := []Human{
    Human{ID:1, Name: "Peter", HairColor: "Black"},
    Human{ID:2, Name: "Paul", HairColor: "Red"},
  } 
  numberOfMammalIDs := Count(mammals)
  numberOfHumanIDs := Count(humans)
  fmt.Println(numberOfMammalIDs)
  fmt.Println(numberOfHumanIDs)
}

我明白了

error prog.go:39: cannot use human (type []Human) as type []Mammal in argument to Count

更多详情请参见 Go Playground http://play.golang.org/p/xzWgjkzcmH

【问题讨论】:

    标签: generics go struct interface


    【解决方案1】:

    在 Go 中,您无法准确地完成您所要求的。在 Go 中最接近的做事方式是这样的,如下面的代码所示:

    type Ids interface{
      Id() int
    }
    
    func (this Mammal) Id() int{
      return this.ID
    } 
    
    func (this Human) Id() int{
      return this.ID
    } 
    
    
    func Count(ms []Ids) *[]string {
    ...
        IDs[i] = strconv.Itoa(int(m.Id()))
    ...
    }
    
    func main(){
      mammals := []Ids{
        Mammal{1, "Carnivorious"},
        Mammal{2, "Ominivorious"},
      }
    
      humans := []Ids{
        Human{ID:1, Name: "Peter", HairColor: "Black"},
        Human{ID:2, Name: "Paul", HairColor: "Red"},
      }
      ...
    }  
    

    这是工作的example

    【讨论】:

    • 感谢一百万 Uvelichitel
    【解决方案2】:

    使用接口而不是具体类型,并使用embedded interfaces,因此常用方法不必在两种类型中都列出:

    type Mammal interface {
        GetID() int
        GetName() string
    }
    
    type Human interface {
        Mammal
    
        GetHairColor() string
    }
    

    下面是这些接口的实现,这些接口基于您使用embedded types(结构)的代码:

    type MammalImpl struct {
        ID   int
        Name string
    }
    
    func (m MammalImpl) GetID() int {
        return m.ID
    }
    
    func (m MammalImpl) GetName() string {
        return m.Name
    }
    
    type HumanImpl struct {
        MammalImpl
        HairColor string
    }
    
    func (h HumanImpl) GetHairColor() string {
        return h.HairColor
    }
    

    但是当然在你的Count() 函数中你只能引用方法而不是实现的字段:

    IDs[i] = strconv.Itoa(m.GetID())  // Access ID via the method: GetID()
    

    并创建您的哺乳动物和人类切片:

    mammals := []Mammal{
        MammalImpl{1, "Carnivorious"},
        MammalImpl{2, "Ominivorious"},
    }
    
    humans := []Mammal{
        HumanImpl{MammalImpl: MammalImpl{ID: 1, Name: "Peter"}, HairColor: "Black"},
        HumanImpl{MammalImpl: MammalImpl{ID: 2, Name: "Paul"}, HairColor: "Red"},
    }
    

    这是Go Playground上的完整工作代码。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-12-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-02-15
      • 1970-01-01
      相关资源
      最近更新 更多