为了账号安全,请及时绑定邮箱和手机立即绑定

是否可以向Swift协议一致性扩展中添加类型约束?

是否可以向Swift协议一致性扩展中添加类型约束?

心有法竹 2019-10-21 09:39:36
我想扩展Array以增加对新协议的一致性-但仅适用于其元素本身符合特定协议的数组。更笼统地说,我想让带有类型参数的类型(无论是协议类型还是具体类型)仅在类型参数与某些约束匹配时才实现协议。从Swift 2.0开始,这似乎是不可能的。有什么我想念的方式吗?例假设我们有以下Friendly协议: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,因为它满足协议的要求。但是,此代码无法编译: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现在,该示例将按照原始问题中的说明进行编译。
查看完整描述

2 回答

?
白猪掌柜的

TA贡献1893条经验 获得超10个赞

编辑:如更新的问题中所述,自Swift 4.1起,现在可以实现


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


您可以获得的最接近的结果是创建一个包装器类型,例如:


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,我的老朋友。


查看完整回答
反对 回复 2019-10-21
  • 2 回答
  • 0 关注
  • 551 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信