如何使用扩展名扩展 swift 协议,以便 类 获得协议定义的已实现变量

how to extend a swift protocol with an extension so that classes get an implemented variable defined by the protocol

情况

以下class:

class User {
    var name = "Max"
    var surname = "Mustermann"
}

和以下协议:

protocol Sharable {
    func share(name: String)
    var isSharable: Bool { get set }
}

意向

以某种方式扩展协议 sharable,以便 User 的子 class 获得 share(:)isSharable 的实现版本。

以下扩展尝试这样做:

extension Sharable where Self: User {
    func share(name: String) { print(name) }
    var isSharable: Bool { return !name.isEmpty }
}

出现问题的地方

创建的子class Admin应该免费获得Sharable的所有功能,无需存储和实现变量和函数。

class Admin: User, Sharable {
    
}

但是Xcode会打印错误:

'Admin' does not conform to protocol 'Sharable'

Xcode 提议如下:

class Admin: User, Sharable {
    var isSharable: Bool
}

现在 Xcode 打印错误:

class 'Admin' has no initializers

问题

有没有办法扩展协议Sharable,使Admin有一个变量isSharable而不定义或初始化它?基本上就像它与函数 share(:) 一起工作一样,它不必由 subclass 实现,因为它是由扩展实现的。

所需的呼叫站点

class ArbitraryObject: User, Sharable {
    // no implementation or initializing of isSharable or share(:)
}


let arbitraryObject = ArbitraryObject()
if arbitraryObject.isSharable {
    arbitraryObject.share(name: arbitraryObject.name)
}

目前您的协议将 isSharable 定义为 { get set }

protocol Sharable {
    func share(name: String)
    var isSharable: Bool { get set }
}

这意味着当您构建扩展时,它实际上并不符合协议

extension Sharable where Self: User {
    func share(name: String) { print(name) }
    var isSharable: Bool { return !name.isEmpty }
}

这是因为您在扩展中将 isSharable 定义为计算 属性。计算属性仅为 get

您可以通过删除 set 要求使您的扩展符合 Sharable 协议。所以你的协议将变成:

protocol Sharable {
    func share(name: String)
    var isSharable: Bool { get }
}