使用 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
有什么方法可以用 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