gpt4 book ai didi

swift - 在 Swift 中约束一个泛型与另一个泛型

转载 作者:搜寻专家 更新时间:2023-10-31 22:47:37 26 4
gpt4 key购买 nike

我遇到了一些协议(protocol)问题:

protocol Baz {
func bar<T>(input:T)
}

函数 bar 是通用的,因为我不希望协议(protocol)本身有一个 Self(它需要在集合中可用)。我有一个定义为协议(protocol)的实现:

class Foo<S>: Baz {
var value:S

init(value:S) {
self.value = value
}

func bar<T>(input:T) {
value = input
}
}

这会产生错误,因为编译器不知道 ST 是同一类型。理想情况下,我应该能够编写如下内容:

    func bar<T where T==S>(input:T) {
value = input
}

    func bar<T:S>(input:T) {
value = input
}

第一种形式给出了“相同类型要求使泛型参数‘S’和‘T’等价”的错误(这正是我想要做的,所以不确定为什么会出错)。第二种形式给了我一个“从非协议(protocol)、非类类型‘S’继承”。

关于如何让它工作或 Swift 中更好的设计模式的任何想法?

更新:正如@luk2302 所指出的,我忘记让Foo 遵守Baz 协议(protocol)

最佳答案

@luk2302 在评论中暗示了很多,但只是为了让 future 的搜索者明确。

protocol Baz {
func bar<T>(input:T)
}

这个协议(protocol)几乎可以肯定是没有用的。它实际上与以下协议(protocol)相同(也几乎完全无用):

protocol Baz {
func bar(input:Any)
}

您很可能的意思(并暗示您的意思):

protocol Baz {
typealias T
func bar(input: T)
}

正如您所注意到的,这使协议(protocol)成为 PAT(具有关联类型的协议(protocol)),这意味着您不能将其直接放入集合中。正如您所注意到的,如果您真的需要它们的集合,通常的解决方案是 type eraser .如果 Swift 会自动为您编写橡皮擦,那会很好,它可能会在未来做到这一点,并且会消除这个问题。也就是说,虽然有点乏味,但书写橡皮擦非常简单。

现在虽然您不能将 PAT 直接放入集合中,但您可以将一般约束的 PAT 放入集合中。所以只要把集合包装成一个约束T的类型,还是没问题的。

如果这些变得复杂,约束代码就会变得乏味且非常重复。然而,这可以通过多种技术来改进。

具有静态方法的通用结构可用于避免重复提供对自由函数的约束。

协议(protocol)可以转换为通用结构(这将类型删除器形式化为主要类型,而不是“根据需要”)。

在很多情况下,协议(protocol)可以被函数替代。例如,鉴于此:

protocol Bar {
typealias T
func bar(input: T)
}

struct Foo : Bar {
func bar(input: Int) {}
}

你不能这样做:

 let bars: [Bar] = [Foo()] // error: protocol 'Bar' can only be used as a generic constraint because it has Self or associated type requirements

但你可以很容易地做到这一点,这同样好:

let bars = [(Int) -> Void] = [Foo().bar]

这对于单一方法协议(protocol)特别强大。

协议(protocol)、泛型和函数的混合比试图将所有内容都强加到协议(protocol)框中要强大得多,至少在协议(protocol)添加一些缺失的功能以实现其 promise 之前是这样。

(针对具体问题给出具体建议会更容易,没有一个答案可以解决所有问题。)

关于swift - 在 Swift 中约束一个泛型与另一个泛型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34483843/

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