gpt4 book ai didi

swift - 是否可以向 Swift 协议(protocol)一致性扩展添加类型约束?

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

我想扩展 Array 以添加对新协议(protocol)的一致性——但仅限于其元素本身符合特定协议(protocol)的数组。

更一般地说,我希望具有类型参数的类型(无论是协议(protocol)还是具体类型)仅在类型参数匹配特定约束时才实现协议(protocol)。

从 Swift 2.0 开始,这似乎是不可能的。有什么方法我想念的吗?

例子

假设我们有 Friendly 协议(protocol):

protocol Friendly {
func sayHi()
}

我们可以扩展现有类型来实现它:

extension String: Friendly {
func sayHi() {
print("Greetings from \(self)!")
}
}

"Sally".sayHi()

我们还可以扩展 Array 来实现 sayHi() ,当它的元素都是 Friendly 时:

extension Array where Element: Friendly {
func sayHi() {
for elem in self {
elem.sayHi()
}
}
}

["Sally", "Fred"].sayHi()

此时,类型[Friendly] 本身应该实现Friendly,因为它满足协议(protocol)的要求。 但是,这段代码无法编译 :

extension Array: Friendly where Element: Friendly {
func sayHi() {
for elem in self {
elem.sayHi()
}
}
}

错误消息是“带有约束的‘Array’类型的扩展不能有继承子句”,这似乎彻底关闭了直接方法的大门。

有间接的解决方法吗?我可以使用一些聪明的技巧吗?也许有一种方法涉及扩展 SequenceType 而不是 Array

一个可行的解决方案将使这段代码编译:

let friendly: Friendly = ["Foo", "Bar"]

更新:这已经在 Swift 4.1 中实现,这是一件美妙的事情!

extension Array: Friendly where Element: Friendly 示例现在可以按照原始问题中给出的方式进行编译。

最佳答案

编辑:如更新后的问题所述,自 Swift 4.1 以来这现在成为可能


目前这在 Swift 中是不可能的(从 Xcode 7.1 开始)。如错误所示,您不能将协议(protocol)一致性(“继承子句”)限制为类型受限的扩展。也许有一天。我不认为有任何深层原因使这成为不可能,但目前尚未实现。

最接近的方法是创建一个包装器类型,例如:

struct FriendlyArray<Element: Friendly>: Friendly {
let array: [Element]
init(_ array: [Element]) {
self.array = array
}
func sayHi() {
for elem in array {
elem.sayHi()
}
}
}

let friendly: Friendly = FriendlyArray(["Foo", "Bar"])

(您可能希望将 FriendlyArray 扩展为 CollectionType。)

有关我自己陷入疯狂尝试使这项工作成功并从边缘爬回来的故事,请参阅 NSData, My Old Friend .

关于swift - 是否可以向 Swift 协议(protocol)一致性扩展添加类型约束?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42118048/

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