首页  >  文章  >  后端开发  >  如何使用接口使 Go 函数通用:类型约束解决方案

如何使用接口使 Go 函数通用:类型约束解决方案

DDD
DDD原创
2024-10-27 02:28:30342浏览

 How to Make Go Functions Generic Using Interfaces: A  Type Constraint Solution

Go 中泛型方法参数:解决类型约束问题

问题:

考虑以下 Go 代码:

<code class="go">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 {
    IDs := make([]string, len(ms))
    for i, m := range ms {
        IDs[i] = strconv.Itoa(int(m.ID))
    }
    return &IDs
}

func main() {
    ... // Code to create Mammal and Human slices
    numberOfMammalIDs := Count(mammals)
    numberOfHumanIDs := Count(humans)
    fmt.Println(numberOfMammalIDs)
    fmt.Println(numberOfHumanIDs)
}</code>

此代码无法编译,并出现错误 error prog.go:39: Cannot use humans (type []Human) as type []Mammal in argument to Count。出现此问题的原因是 Count 函数需要一个 Mammal 结构数组,但我们传递的是一个 Human 结构数组。我们如何解决这个类型约束并使 Count 函数足够通用以接受任何具有 ID 属性的类型?

解决方案:

1.使用接口:

用定义 ID 属性的接口替换具体类型。例如:

<code class="go">type Mammal interface {
    GetID() int
}

type Human interface {
    Mammal
    GetHairColor() string
}</code>

2。嵌入接口:

为了避免在哺乳动物和人类接口中重复 ID 方法,请使用嵌入接口:

<code class="go">type MammalImpl struct {
    ID int
    Name string
}

func (m MammalImpl) GetID() int {
    return m.ID
}

type HumanImpl struct {
    MammalImpl
    HairColor string
}</code>

3.更新计数函数:

修改计数函数以使用 Mammal 接口而不是具体的 Mammal 类型:

<code class="go">func Count(ms []Mammal) *[]string {
    IDs := make([]string, len(ms))
    for i, m := range ms {
        IDs[i] = strconv.Itoa(m.GetID())
    }
    return &IDs
}</code>

4.创建符合接口的切片:

创建实现哺乳动物接口的切片:

<code class="go">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"},
}</code>

5.用法示例:

现已成功编译的用法示例:

<code class="go">package main

import (
    "fmt"
    "strconv"
)

type Mammal interface {
    GetID() int
}

type Human interface {
    Mammal
    GetHairColor() string
}

type MammalImpl struct {
    ID   int
    Name string
}

func (m MammalImpl) GetID() int {
    return m.ID
}

type HumanImpl struct {
    MammalImpl
    HairColor string
}

func (h HumanImpl) GetHairColor() string {
    return h.HairColor
}

func Count(ms []Mammal) *[]string {
    IDs := make([]string, len(ms))
    for i, m := range ms {
        IDs[i] = strconv.Itoa(m.GetID())
    }
    return &IDs
}

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

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

    numberOfMammalIDs := Count(mammals)
    numberOfHumanIDs := Count(humans)
    fmt.Println(numberOfMammalIDs) // [1 2]
    fmt.Println(numberOfHumanIDs) // [1 2]
}</code>

通过使用接口和嵌入式接口,我们使 Count 函数足够通用,可以处理任何实现哺乳动物接口,有效解决类型约束问题。

以上是如何使用接口使 Go 函数通用:类型约束解决方案的详细内容。更多信息请关注PHP中文网其他相关文章!

声明:
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn