迹忆客 专注技术分享

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

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

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

通常,我们不希望或不需要对泛型使用的类型进行任何限制,因为我们不一定关心特定数据。 但是,其他时候,我们需要能够限制泛型使用的类型。 例如,如果我们正在创建一个泛型 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 进行申请,经作者同意之后,转载请以链接形式注明出处

本文地址:

相关文章

Golang 中的零值 Nil

发布时间:2023/04/27 浏览次数:166 分类:Go

本篇文章介绍 nil 在 Golang 中的含义,nil 是 Go 编程语言中的零值,是众所周知且重要的预定义标识符。

Golang 中的 Lambda 表达式

发布时间:2023/04/27 浏览次数:93 分类:Go

本篇文章介绍如何在 Golang 中创建 lambda 表达式。Lambda 表达式似乎不存在于 Golang 中。 函数文字、lambda 函数或闭包是匿名函数的另一个名称。

Go 中的深度复制

发布时间:2023/04/27 浏览次数:90 分类:Go

当我们尝试生成对象的副本时,深层副本会准确复制原始对象的所有字段。 此外,如果它有任何对象作为字段,也会制作这些对象的副本。本篇文章介绍如何在 Golang 中进行深度复制。

在 Go 中捕获 Panics

发布时间:2023/04/27 浏览次数:66 分类:Go

像错误一样,Panic 发生在运行时。 换句话说,当您的 Go 程序中出现意外情况导致执行终止时,就会发生 Panics。让我们看一些例子来捕捉 Golang 中的Panics。

Go 中的日志级别

发布时间:2023/04/27 浏览次数:199 分类:Go

本篇文章介绍如何在 Golang 中创建和使用日志级别。Go 中的日志级别。Golang提供了一个日志包,名为log,是一个简单的日志包。 这个包不提供分级日志; 如果我们想要分级日志记录,我们必须

在 Go 中使用断言

发布时间:2023/04/27 浏览次数:181 分类:Go

本篇文章介绍了 assert 在 GoLang 中的使用。在 Go 语言中使用断言:GoLang 不提供对断言的任何内置支持,但我们可以使用来自 Testify API 的广泛使用的第三方包断言。

Go 中的随机数生成

发布时间:2023/04/27 浏览次数:114 分类:Go

本篇文章介绍如何在 Go 语言中使用随机数生成功能。Go 中的随机数生成 Go 语言为随机数生成功能提供内置支持。 内置包 math 有方法 rand(),用于随机数生成。

GoLang 电子邮件验证器

发布时间:2023/04/27 浏览次数:195 分类:Go

本篇文章介绍如何在 Go 语言中验证电子邮件。电子邮件需要特定格式; 否则,它们将无法工作。

扫一扫阅读全部技术教程

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

最新推荐

教程更新

热门标签

扫码一下
查看教程更方便