Я использую исходный код для генерации некоторого кода на моделях, чтобы сделать использование KeyPath более динамичным, чем предполагалось.Чтобы установить значение с помощью KepPath, необходимо привести его к конкретному типу, поскольку KeyPath не являются ковариантными.
, поэтому для KeyPath, например \Item.category
(где категория :String?
), нужен конкретный типчтобы выглядеть примерно так ReferenceWritableKeyPath<Item, String?>
Вы не можете написать значение, используя self[keyPath: someKeyPath]
, если someKeyPath
не правильный тип.PartiakKeyPath
и AnyKeyPath
не работают.У меня есть enum, key
, у которого есть вычисленная переменная keyPath
, которая возвращает AnyKeyPath
type(of: key.keyPath).valueType
печатает как Optional<String>
, когда я вызываю этот метод на перечислении
func writeableKeyPath<T>(kt: T) -> ReferenceWritableKeyPath<Item, T?>? {
return self.keyPath as? ReferenceWritableKeyPath<Item, T?>
}
вот так
key.writeableKeyPath(kt: type(of: key.keyPath).valueType)
Возврат всегда равен нулю из-за этого:
Could not cast value of type 'Swift.ReferenceWritableKeyPath<SourceryDemo.Item, Swift.Optional<Swift.String>>' (0x10a8a5f88)
to 'Swift.ReferenceWritableKeyPath<SourceryDemo.Item, Swift.Optional<Any.Type>>'
В основном это не вывод Swift.Optional<Swift.String>
и принуждение к Swift.Optional<Any.Type>
Если я изменяю сигнатуру метода на использование T.Type
и передаю String.self
, это работает, но я пытаюсь сделать это, не нуждаясь в этой информации во время компиляции.И я не могу использовать T.Type
при использовании type(of:)
func writeableKeyPath<T>(kt: T.Type) -> ReferenceWritableKeyPath<Item, T?>? { ... }
key.writeableKeyPath(kt: String.self)
Это просто какая-то дополнительная магия, которую я пытаюсь извлечь из этого, так как у меня уже работают эти методы:
func set<T, V: KeyValueEnum>(value: T, forKey key: V)
func value(forKey string: String) -> Any?
Я знаю, что-то вроде этого выполнимо с NSObject
и @objc
, но пытался достичь этого без них.