迹忆客 专注技术分享

当前位置:主页 > 学无止境 > 编程语言 >

在 Go 中如何使用泛型 入门 - 限制泛型类型

作者:迹忆客 最近更新:2022/08/01 浏览次数:

通常,我们不希望或不需要对泛型使用的类型进行任何限制,因为我们不一定关心特定数据。 但是,其他时候,我们需要能够限制泛型使用的类型。 例如,如果我们正在创建一个泛型 Sorter 类型,则可能希望将其泛型类型限制为具有 Compare 方法的类型,以便 Sorter 可以比较它所持有的项目。 如果不包括该限制,则这些值甚至可能没有 Compare 方法,并且我们的 Sorter 将不知道如何比较它们。

在本节中,我们将为卡片创建一个新的 Card 接口,然后更新我们的 Deck 以仅允许添加卡片类型。

要开始更新,请打开 main.go 文件并添加 Card 接口:

import (
...
)

type Card interface {
    fmt.Stringer

    Name() string
}

我们的 Card 接口的定义与过去可能使用的任何其他 Go 接口相同; 将其与泛型一起使用没有特殊要求。 在此 Card 接口中,要想被视为 Card,它必须实现 fmt.Stringer 类型(它必须具有 Card 已有的 String 方法),并且它还必须具有返回 a 字符串值。

接下来,更新我们的 TradingCardPlayingCard 类型以添加新的 Name 方法,除了现有的 String 方法,因此它们实现 Card 接口:

...

type TradingCard struct {
    ...
}

...

func (tc *TradingCard) Name() string {
    return tc.String()
}

...

type PlayingCard struct {
    ...
}

...

func (pc *PlayingCard) Name() string {
    return pc.String()
}

TradingCardPlayingCard 已经有实现 fmt.Stringer 接口的 String 方法。 所以要实现 Card 接口,只需要添加新的 Name 方法即可。 另外,由于 fmt.Stringer 已经实现了返回卡片的名称,您可以只返回 Name 的 String 方法的结果。

现在,更新我们的 Deck,使其仅允许将 Card 类型用于 C:

...

type Deck[C Card] struct {
    cards []C
}

在此更新之前,我们有 C any 用于类型限制(称为类型约束),这并不是什么限制。 由于 anyinterface{} 的含义相同,因此它允许将 Go 中的任何类型用于 C 类型参数。 现在我们已经用新的 Card 接口替换了 any,Go 编译器将确保在编译程序时用于 C 的任何类型都实现 Card。

由于我们添加了此限制,现在可以在我们的 Deck 类型的方法中使用 Card 提供的任何方法。 如果我们希望 RandomCard 也打印出正在绘制的卡片的名称,它可以访问 Name 方法,因为它是 Card 接口的一部分。 我们将在下一篇文章中看到这一点。

这几个更新是需要进行的唯一更新,以将我们的 Deck 类型限制为仅使用 Card 值。 保存更改后,使用 go run 运行更新的程序:

$ go run main.go

输出的结果如下

--- drawing playing card ---
drew card: 5 of Clubs
card suit: Clubs
card rank: 5
--- drawing trading card ---
drew card: Droplets
card collectable name: Droplets

我们会看到,除了选择不同的卡之外,输出并没有改变。 由于我们的更新仅将值限制为已经使用的类型,因此程序的功能没有改变。

在本篇文章中,我们添加了新的 Card 接口并更新了 TradingCardPlayingCard 来实现该接口。 还更新了 Deck 的类型约束以将其类型参数限制为仅实现 Card 接口的类型。

不过,到目前为止,我们只创建了一个通用结构类型。 除了创建泛型类型,Go 还允许你创建泛型函数。

本站文章均为原创或翻译,转载请发邮件至 1244347461@qq.com 进行申请,未经许可,禁止转载。经作者同意之后,转载请以链接形式注明出处

本文地址:

扫一扫阅读全部技术教程

社交账号
  • https://www.github.com/onmpw
  • qq:1244347461

热门文章

教程更新

热门标签

Go
扫码一下
查看教程更方便