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

标签 swift generics

我想扩展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 中实现,它是一件美丽的事情!

扩展数组:友好,其中元素:友好示例现在按照原始问题中给出的方式进行编译。

最佳答案

编辑:正如更新的问题中所述,自 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/36465941/

相关文章:

c# - 为泛型类实现 IComparable<T> 接口(interface)以比较类型 T

uitableview - 分组 TableView - 圆形单元格?

java - int 数组的通用交换方法

c# - 为什么我不能将泛型类型的一个实例化转换为另一个实例化?

ios - 启动 View Controller 并删除点击栏。 swift

c# - 如何在C#中继承WPF控件并同时使用泛型类?

c# - 泛型和 LINQ to XML

arrays - Swift 中数组的可选 Int - 平均函数

ios - 默认情况下启用推文按钮当文本在 Twitter 共享扩展中超过 280 个字符时

swift - 如何在swift中的tableview中的didselectrow方法中点击内容 View