简体   繁体   中英

Reference to self with Swift 4's KeyPath

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM