Is there any way to reference self
with Swift 4's new KeyPath
s?
Something like this works fine, we can address a property of an object:
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)
But addressing an object itself seems impossible to me:
let strings = ["string-one", "string-two"]
report(array: strings, keyPath: \String.self) // would not compile
I suppose there should be some obvious way for this?
EDIT:
Or simply:
let s = "text-value"
print(s[keyPath: \String.description]) // works fine
print(s[keyPath: \String.self]) // does not compile
Unfortunately, this isn't something Swift keypaths currently support. However, I do think this is something they should support (with the exact syntax you're attempting to use, eg \\String.self
). All expressions have an implicit .self
member that just evaluates to the expression, so it seems like a perfectly natural extension to allow .self
in keypaths ( Edit: This is now something that's being pitched ).
Until supported (if at all), you can hack it with a protocol extension that adds a computed property that just forwards to 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])
You just need to conform types that you want to use "self keypaths" with to KeyPathSelfProtocol
.
Yes there is a way to reference self
but it is not available in Swift 4. It was implemented for Swift 5 in september 2018 and it is called the Identity key path .
You use it like you suggested
let s = "text-value"
print(s[keyPath: \String.self]) // works in Swift 5.0
Even though Swift 5 is not yet released, you can already try it out by downloading a development version at: https://swift.org/download/#releases
The behavior of keyPath
is
the same as
similar to Key-Value Coding: Getting the value of a member of the class / struct by key
subscription.
In Swift self
is not a member of the class, description
is.
What result would you expect with
report(array: wrappers, keyPath: \Wrapper.self)
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.