有没有办法用 Swift 4 的新KeyPath
来引用self
?
像这样的东西工作正常,我们可以处理对象的属性:
func report(array: [Any], keyPath: AnyKeyPath) {
print(array.map({ $0[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
不幸的是,这不是 Swift 密钥路径目前支持的内容。但是,我确实认为这是他们应该支持的东西(使用您尝试使用的确切语法,例如String.self
(。所有表达式都有一个隐式.self
成员,该成员仅计算表达式,因此允许在键路径中进行.self
似乎是一个完全自然的扩展(编辑:现在正在提出
在支持之前(如果有的话(,您可以使用协议扩展来破解它,该扩展添加一个仅转发到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])
您只需要将要使用"自身键路径"的类型与KeyPathSelfProtocol
是的,有一种方法可以引用self
但它在 Swift 4 中不可用。它于 2018 年 9 月为 Swift 5 实现,称为身份密钥路径。
你按照你的建议使用它
let s = "text-value"
print(s[keyPath: String.self]) // works in Swift 5.0
尽管 Swift 5 尚未发布,但您已经可以通过下载开发版本来试用它: https://swift.org/download/#releases
keyPath
的行为与类似于键值编码相同:通过key
订阅获取类/结构成员的值。
在 Swift 中,self
不是类的成员,description
是。
你会期待什么结果
report(array: wrappers, keyPath: Wrapper.self)