swift - 如何仅为类类型提供 subsript 的默认协议一致性?
问题描述
用“类”标记 CacheManager 解决了我的问题。
情况是这样的:一个简单的缓存器,变异的 get 不是我想要的,那么对于引用类型或类类型应该怎么做?
protocol Cacher {
associatedtype K
associatedtype V
subscript (key: K) -> V? {get set}
}
protocol MemoryCacher: Cacher {}
protocol FileCacher: Cacher {}
更新了。添加 PrimayCacher | SecondaryCacher 关联类型
protocol CacheManager {
associatedtype Key
associatedtype Value
associatedtype PrimaryCacher: MemoryCacher where PrimaryCacher.K == Key, PrimaryCacher.V == Value
associatedtype SecondaryCacher: FileCacher where SecondaryCacher.K == Key, SecondaryCacher.V == Value
var primaryCacher: PrimaryCacher { get set }
var secondaryCacher: SecondaryCacher{ get set }
subscript(key: Key) -> Value? { get set }
}
//try to provide a default subscript conformance, but actually not for the `mutating` get
extension CacheManager {
subscript(key: Key) -> Value? {
mutating get {
guard let result = primaryCacher[key] else {
if let value = secondaryCacher?[key] {
primaryCacher[key] = value // the mutating is required for this
return value
}
return nil
}
return result
}
set {
primaryCacher[key] = newValue
secondaryCacher?[key] = newValue
}
}
}
解决方案
你只需要添加一个类型限制AnyObject
,所有类都符合。
extension CacherManager where Self: AnyObject {
subscript(key: Key) -> Value? {
get {
guard let result = primaryCacher[key] else {
if let value = secondaryCacher?[key] {
primaryCacher[key] = value // the mutating is required for this
return value
}
return nil
}
return result
}
set {
primaryCacher[key] = newValue
secondaryCacher?[key] = newValue
}
}
}
我还必须稍微修改您CacheManager
的代码声明以编译并添加所需的协议方法,MemoryCacher
并且FileCacher
您在问题中省略了这些方法。
protocol Cacher {
associatedtype K
associatedtype V
subscript (key: K) -> V? {get set}
}
class MemoryCacher<K, V>: Cacher {
private var value: V?
subscript(key: K) -> V? {
get {
return value
}
set {
value = newValue
}
}
}
class FileCacher<K, V>: Cacher {
private var value: V?
subscript(key: K) -> V? {
get {
return value
}
set {
value = newValue
}
}
}
protocol CacheManager {
associatedtype Key
associatedtype Value
var primaryCacher: MemoryCacher<Key,Value> { get set }
var secondaryCacher: FileCacher<Key,Value>? { get set }
subscript(key: Key) -> Value? { get set }
}
推荐阅读
- python - 使用 Opencv 和 Python 训练 SVM 和预测
- python - 是否可以通过 scikit.learn 创建一个预测分层类/标签的 RandomForestClassifier?
- arrays - 打字稿:如何在数组中按分钟分组?
- java - Spring MVC - 来自过滤器的内容类型感知响应
- javascript - Google Apps 脚本:在对象文档中找不到函数 insertText
- python - 管道 - 类型错误:fit_transform() 接受 2 个位置参数,但给出了 3 个
- ios - 在 Cordova iOS 包中找不到 `OBJROOT="$OBJROOT"` 以尝试修复构建错误:xcodebuild:命令失败,退出代码为 65
- mysql - 错误:ER_NO_DB_ERROR:始终使用数据库限定对象引用时未选择数据库(Node.js + MySql)
- jsf - 未找到来自外部 Web 项目的引用组合
- android - Apollo codegen 安装任务上的 Apollo Android 错误