存储异构键路径数组

如何解决存储异构键路径数组

我有一个类似于:

gactions push

我正在尝试存储一个异构的更新数组,以便以后可以使用它们来设置值。像这样的东西。

class MyObject {
  var title:String? = nil
  var value:Int? = nil
  var otherData:[String] = []
}

然而,这当然在 getUpdates() 中读取 class SomeFormThing { func getUpdates() -> [WritableKeyPath<MyObject,Any> : Any] { var updates:[WritableKeyPath<MyObject,Any> : Any] updates[\MyObject.title] = "New Title" updates[\MyObject.value] = 0 updates[\MyObject.value] = ["Other","Values"] return updates } } class SyncManager { var form:SomeFormThing = SomeFormThing() var sync:MyObject = MyObject() func updateValues() { let updates = form.getUpdates() for key in updates.keys { sync[forKeyPath: key] = updates[key] } } } 的行上存在编译问题。

需要有一组异构的可写键路径,然后我可以用它来设置值。鉴于泛型通常是如何工作的,我不明白为什么 String 不能等同于 Any 泛型,因为类型是向下转型。

解决方法

Swift 集合不喜欢异构。此外,键路径是泛型,为了类型安全,泛型不是协变的。

所以你不能在一个集合中组合不同的类型——除非你键入擦除。当然,如果你这样做,你必须稍后取消类型擦除,这很麻烦。这就像一个蟑螂汽车旅馆:包裹的类型进去但它们不会出来,除非你用手引出它们。

例如:

    struct MyObject {
      var title:String
      var value:Int
    }

    // okay,roaches go in...
    let kp1 = \MyObject.title
    let kp2 = \MyObject.value
    let dict : [PartialKeyPath<MyObject>:Any] = [kp1:"Yo",kp2:1]

    var object = MyObject(title: "Ha",value: 0)

    // but now what? how can we apply our `dict` entries to `object`? well...
    for (kp,val) in dict {
        switch (kp,val) {
        case (let kp2 as WritableKeyPath<MyObject,String>,let val2 as String):
            object[keyPath:kp2] = val2
        case (let kp2 as WritableKeyPath<MyObject,Int>,let val2 as Int):
            object[keyPath:kp2] = val2
        default:break
        }
    }
    print(object) // yep,we did it,sort of

所以你看,你可以做到,但你必须单独处理每一种可能的属性类型。您已将 PartialKeyPath 的 Partial 和 Any 中的类型隐藏起来,现在将它们强制公开由您决定。

也就是说,我实际执行此操作的方法是为 MyObject 提供一个通用的 update 方法,并且一次只调用一个更改:

    struct MyObject {
        var title:String
        var value:Int
        mutating func update<T>(_ kp:WritableKeyPath<Self,T>,to val:T) {
            self[keyPath:kp] = val
        }
    }

所以:

    object.update(\.title,to: "Teehee")
    object.update(\.value,to: 42)

请注意,您不能直接从 dict 中的条目执行此操作,因为您隐藏了类型。泛型不会等到运行时才查看“真正”是什么类型;它是由编译器解析的,因此类型必须是已知的——通过说 PartialKeyPath 和 Any 你已经un 知道类型。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其他元素将获得点击?
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。)
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbcDriver发生异常。为什么?
这是用Java进行XML解析的最佳库。
Java的PriorityQueue的内置迭代器不会以任何特定顺序遍历数据结构。为什么?
如何在Java中聆听按键时移动图像。
Java“Program to an interface”。这是什么意思?
Java在半透明框架/面板/组件上重新绘画。
Java“ Class.forName()”和“ Class.forName()。newInstance()”之间有什么区别?
在此环境中不提供编译器。也许是在JRE而不是JDK上运行?
Java用相同的方法在一个类中实现两个接口。哪种接口方法被覆盖?
Java 什么是Runtime.getRuntime()。totalMemory()和freeMemory()?
java.library.path中的java.lang.UnsatisfiedLinkError否*****。dll
JavaFX“位置是必需的。” 即使在同一包装中
Java 导入两个具有相同名称的类。怎么处理?
Java 是否应该在HttpServletResponse.getOutputStream()/。getWriter()上调用.close()?
Java RegEx元字符(。)和普通点?