gpt4 book ai didi

swift - 为什么我们在这里需要一个泛型?协议(protocol)还不够吗?

转载 作者:行者123 更新时间:2023-11-28 06:18:28 25 4
gpt4 key购买 nike

我在网上找到了以下关于将泛型与协议(protocol)一起使用的示例,但是我不明白为什么我们根本需要泛型,而我们所需要的只是使用协议(protocol)。

我们定义一个协议(protocol):

protocol Healthy {
mutating func setAlive(status: Bool)
var health: Int { get }
}

然后是一个使用通用协议(protocol)的函数

func check<T:Healthy>(inout object: T) {
if (object.health <= 0) {
object.setAlive(false)
}
}

我已将代码更改如下,一切仍然正常。

func check( object: inout Healthy) {
if (object.health <= 0) {
object.setAlive(status: false)
}
}

还是不行?

我能想到在那里使用泛型的唯一原因是,如果它是一个具有关联类型的协议(protocol)并且它不能用作实例。

最佳答案

他们表达不同的东西。与

func check(object: inout Healthy) {

object 参数可以是任何 Healthy 符合的实例。因此,您可以这样做:

protocol Healthy {}

struct Foo : Healthy {}
struct Bar : Healthy {}

func check(object: inout Healthy) {
object = Bar()
}

var h: Healthy = Foo()
check(object: &h)
print(h) // Bar()

我们调用了 check(object:) 并传递了 h(它包含一个 Foo 实例)作为 inout 参数,但最终 h 持有一个 Bar 实例。

您会注意到,这意味着我们不能简单地使用具体类型的 inout 参数调用 check(object:)。以下不编译:

var h = Foo()

// compiler error: Cannot pass immutable value as inout argument:
// implicit conversion from 'Foo' to 'Healthy' requires a temporary
check(object: &h)

因为 check(object:) 可以分配一个 任意 Healthy 符合 object 参数的实例,这不可分配给 Foo 变量。

然而,随着

func check<T : Healthy>(object: inout T) {

object 参数是符合Healthy 的单个特定具体类型(并且此类型在调用站点得到满足)。您不能只为它分配一个任意的符合 Healthy 的实例,因为它可能与作为 inout 参数传递的变量类型不兼容。

因此现在允许您使用具体类型的 inout 参数调用它。我们现在可以说:

protocol Healthy {
var alive: Bool { get set }
}

struct Foo : Healthy {
var alive: Bool
}
struct Bar : Healthy {
var alive: Bool
}

func check<T : Healthy>(object: inout T) {

object.alive = false

// illegal
// object = Bar()
}

var h = Foo(alive: true)
check(object: &h)

(注意 h 可以输入为 Foo)

因此在大多数情况下,您可能希望使该方法具有通用性,而不是使用协议(protocol)类型的 inout 参数,因为您可能希望处理具体类型。

关于swift - 为什么我们在这里需要一个泛型?协议(protocol)还不够吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44387949/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com