问题描述
情况
以下类:
class User {
var name = "Max"
var surname = "Mustermann"
}
以及以下协议:
protocol Sharable {
func share(name: String)
var isSharable: Bool { get set }
}
意图
以某种方式扩展协议 sharable
,以便 User
的子类获得 share(:)
和 isSharable
的实现版本。
以下扩展程序尝试执行此操作:
extension Sharable where Self: User {
func share(name: String) { print(name) }
var isSharable: Bool { return !name.isEmpty }
}
问题发生在哪里
创建的子类 Admin
应该免费获得 Sharable
的所有功能,无需存储和实现变量和函数。
class Admin: User,Sharable {
}
但是Xcode会打印错误:
“管理员”不符合“可共享”协议
Xcode 提出以下建议:
class Admin: User,Sharable {
var isSharable: Bool
}
现在 Xcode 打印错误:
“Admin”类没有初始化器
问题
有没有办法扩展协议 Sharable
以便 Admin
有一个变量 isSharable
而无需定义或初始化它?基本上就像它与函数share(:)
,它不必由子类实现,因为它是由扩展实现的。
期望的呼叫站点
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
。
您可以通过删除 Sharable
要求使您的扩展符合 set
协议。所以你的协议会变成:
protocol Sharable {
func share(name: String)
var isSharable: Bool { get }
}