struct Foo { var bar: String = “” var baz: Int? = nil}let values: [Any] = [“foo”,1337]let fooPaths: [PartialKeyPath<Foo>] = [\Foo.bar,\Foo.baz] let protoFoo = Foo()
如何创建迭代这些键路径和值的for循环,并在类型匹配两者且keypath是可写的时将值分配给键路径?
注意:它必须使用泛型来完成,因为Foo可以具有任何类型的属性(当然,除了类型Foo).
我尝试过这样的东西:
func setKeyOnRoot<Root,Value>(_ root: Root,value: Value,key: PartialKeyPath<Root>) -> Root { var root = root if let writableKey = key as? WritableKeyPath<Root,Value> { root[keyPath: writableKey] = value } return root}
但由于在调用此函数之前必须将值转换为Any,因此运行时无法看到类型Value的含义.
解决方法 此实现类似于您作为您尝试的方法示例提供的内容,我相信它会产生您正在寻找的结果:struct WritableKeyPathApplicator<Type> { private let applicator: (Type,Any) -> Type init<ValueType>(_ keyPath: WritableKeyPath<Type,ValueType>) { applicator = { var instance =var protoFoo = Foo()for (applicator,value) in zip(fooPaths,values) { protoFoo = applicator.apply(value: value,to: protoFoo)}if let value = as? ValueType { instance[keyPath: keyPath] = value } return instance } } func apply(value: Any,to: Type) -> Type { return applicator(to,value) }}struct Foo { var bar: String = "" var baz: Int? = nil}let values: [Any] = ["foo",1337]let fooPaths: [WritableKeyPathApplicator<Foo>] = [WritableKeyPathApplicator(\Foo.bar),WritableKeyPathApplicator(\Foo.baz)]let protoFoo = zip(fooPaths,values).reduce(Foo()){ return .0.apply(value: .1,to: ) }print(protoFoo) // prints Foo(bar: "foo",baz: Optional(1337))
这个版本做同样的事情,但使用原始问题中指定的for循环可以用以下代码替换倒数第二行:
请注意,需要某些类型擦除才能使用在同一根类型上运行但具有不同值类型的单个keyPath数组.但是,在运行时,WritableKeyPathApplicator内的闭包可以专门为每个keyPath强制转换为正确的原始值类型,并且如果它是错误的类型(如上面的示例代码中),则默默地跳过该值以设置它,否则它可能会抛出错误或向控制台等打印更多有用的信息
总结以上是内存溢出为你收集整理的泛型 – 在Swift 4中,当键路径和值的类型是通用的但是相同时,如何分配给键路径?全部内容,希望文章能够帮你解决泛型 – 在Swift 4中,当键路径和值的类型是通用的但是相同时,如何分配给键路径?所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)