使用 Swift 4 的 KeyPath 引用自身

Reference to self with Swift 4's KeyPath

有什么方法可以用 Swift 4 的新 KeyPath 引用 self 吗?

这样的事情很好,我们可以解决一个对象的属性:

func report(array: [Any], keyPath: AnyKeyPath) {
    print(array.map({ [=11=][keyPath: keyPath] }))
}

struct Wrapper {
    let name: String
}

let wrappers = [Wrapper(name: "one"), Wrapper(name: "two")]
report(array: wrappers, keyPath: \Wrapper.name)

但是对我来说,解决一个对象本身似乎是不可能的:

let strings = ["string-one", "string-two"]
report(array: strings, keyPath: \String.self) // would not compile

我想应该有一些明显的方法吗?

编辑:

或者简单地说:

let s = "text-value"
print(s[keyPath: \String.description]) // works fine
print(s[keyPath: \String.self]) // does not compile

keyPath的行为类似Key-Value编码:获取成员的值 的 class / 由 key 订阅结构。

在Swift中self不是class的成员,description是。

您希望

得到什么结果
report(array: wrappers, keyPath: \Wrapper.self)

不幸的是,Swift 键路径目前不支持此功能。但是,我确实认为这是他们 应该 支持的东西(使用您尝试使用的确切语法,例如 \String.self)。所有表达式都有一个隐式的 .self 成员,它只计算表达式的值,所以它似乎是一个完美的自然扩展,允许在键路径中使用 .self编辑: 这是现在 something that's being pitched).

直到支持(如果有的话),你可以用一个协议扩展来破解它,添加一个计算的 属性 只是转发到 self:

protocol KeyPathSelfProtocol {}
extension KeyPathSelfProtocol {
  var keyPathSelf: Self {
    get { return self }
    set { self = newValue }
  }
}

extension String : KeyPathSelfProtocol {}

let s = "text-value"
print(s[keyPath: \String.description])
print(s[keyPath: \String.keyPathSelf])

您只需要将要使用 "self keypaths" 的类型与 KeyPathSelfProtocol 一致。

是的,有一种方法可以参考 self,但它在 Swift 4 中不可用。它是在 2018 年 9 月为 Swift 5 实现的,它被称为 Identity key path.

您按照建议使用它

let s = "text-value"
print(s[keyPath: \String.self]) // works in Swift 5.0

尽管 Swift 5 尚未发布,但您已经可以通过下载开发版来试用它:https://swift.org/download/#releases