swift - 在 Swift 中,如何实现一个通用系统,通过为不同的键路径注册处理器来处理类型?
问题描述
我想实现一个系统,允许我通过为不同的关键路径注册处理器来一般地处理类型。
系统的一个特征应该是composition
,因此每个处理器都应该扩展一个通用的通用协议Processor
。
使用示例:
struct Language {
var name = "Swift"
var version = 5.3
}
var processor = TypeProcessor<Language>()
processor.add(procesor: VersionProcessor(), keypath: \.version)
processor.add(procesor: NameProcessor(), keypath: \.name)
var input = Language()
processor.process(value: input)
// Languge version: 5.3
// Languge name: Swift
解决方案
您可以使用“处理器”的继承,而不是尝试擦除属性类型,其中子类是根对象和属性类型的泛型,并且具有属性键路径。
protocol Processor {
associatedtype T
func process(value: T)
}
class AnyProcessor<Value>: Processor {
func process(value: Value) {
}
}
final class KeyPathProcessor<Root, P: Processor>: AnyProcessor<Root> {
typealias Value = P.T
let keyPath: KeyPath<Root, Value>
let processor: P
init(keyPath: KeyPath<Root, Value>, processor: P) {
self.keyPath = keyPath
self.processor = processor
}
override func process(value: Root) {
processor.process(value: value[keyPath: keyPath])
}
}
struct ObjectProcessor<T>: Processor {
var processors = [AnyKeyPath: AnyProcessor<T>]()
mutating func add<P: Processor, V>(processor: P, keypath: KeyPath<T, V>) where P.T == V {
self.processors[keypath] = KeyPathProcessor(keyPath: keypath, processor: processor)
}
func process(value: T) {
for (_, processor) in processors {
processor.process(value: value)
}
}
}
推荐阅读
- mysql - 连接具有可变表名的表
- git - 尽管更改是远程进行的,但 Git 说是最新的
- phpmyadmin - 尽管将 $cfg['Servers'][$i]['auth_type'] 更改为从 cookie 配置,phpmyadmin 仍不允许创建数据库
- angular - Angular 7 Clarifai api“全局未在 Object../node_modules/clarifai/dist/index.js 中定义”
- dart - 如何阻止 Firestore 事务重试
- asp.net-mvc - 找不到文件或目录
- java - 如何在java中编写Szudzik的函数
- packer - 如何在打包器中加载常用的 bash 脚本
- java - 在真实设备上顺时针旋转活动的问题
- javascript - 如何将我本地的 webhook 连接到 dialogflow?