Get all key paths from a structure in Swift 4

Let's say I have this structure:

struct MyStruct {
    let x: Bool
    let y: Bool
}

In Swift 4, we can now access its properties using the interface myStruct[keyPath: \MyStruct.x].

I need a way to access all key paths, for example:

extension MyStruct {

    static func getAllKeyPaths() -> [WritableKeyPath<MyStruct, Bool>] {
        return [
            \MyStruct.x,
            \MyStruct.y
        ]
    }

}

But obviously, without having to manually declare each property in an array.

How can i achieve this?

+11
source share
2 answers

DENIAL OF RESPONSIBILITY:

Please note that the following code is for educational purposes only and should not be used in a real application , and it may contain many errors / strange behavior, if used KeyPathin this way.

Answer:

, , :)

API .

API- KeyPath KeyPath , " ".

, , struct API , KeyPath.

Swift 4.2:

protocol KeyPathListable {
  // require empty init as the implementation use the mirroring API, which require
  // to be used on an instance. So we need to be able to create a new instance of the 
  // type.
  init()

  var _keyPathReadableFormat: [String: Any] { get }
  static var allKeyPaths: [KeyPath<Foo, Any?>] { get }
}

extension KeyPathListable {
  var _keyPathReadableFormat: [String: Any] {
    let mirror = Mirror(reflecting: self)
    var description: [String: Any] = [:]
    for case let (label?, value) in mirror.children {
      description[label] = value
    }
    return description
  }

  static var allKeyPaths: [KeyPath<Self, Any?>] {
    var keyPaths: [KeyPath<Self, Any?>] = []
    let instance = Self()
    for (key, _) in instance._keyPathReadableFormat {
      keyPaths.append(\Self._keyPathReadableFormat[key])
    }
    return keyPaths
  }
}

struct Foo: KeyPathListable {
  var x: Int
  var y: Int
}

extension Foo {
  // Custom init inside an extension to keep auto generated 'init(x:, y:)'
  init() {
    x = 0
    y = 0
  }
}

let xKey = Foo.allKeyPaths[0]
let yKey = Foo.allKeyPaths[1]

var foo = Foo(x: 10, y: 20)
let x = foo[keyPath: xKey]!
let y = foo[keyPath: yKey]!

print(x)
print(y)

, (, - API , ).

+3

Swift.

:

KeyPath

, Swift for TensorFlow Swift TensorFlow, Swift:

0

Source: https://habr.com/ru/post/1686703/


All Articles