简体   繁体   English

如何在Swift KeyPath的类型为KeyPath时获取基础值 <Root, Value!> ?

[英]How to get the underlying Value from a Swift KeyPath when its type is KeyPath<Root, Value!>?

Take a look at the following code: 看看下面的代码:

struct Something {
  var s: String! // Implicitly Unwrapped Optional
}

func bind<T, V>(keyPath: WritableKeyPath<T, V?>) {
}

bind(\Something.s)

The code above does not compile. 上面的代码不能编译。 If we change the signature of bind to bind<T, V>(keyPath: WritableKeyPath<T, V>) then it does compile, but the problem is that the type of V is String! 如果我们将bind的签名更改为bind<T, V>(keyPath: WritableKeyPath<T, V>)然后它编译,但问题是V的类型是String! and I need to get the underlying type, in this case String . 我需要获取底层类型,在本例中为String

We can solve the problem as follows: 我们可以解决以下问题:

func bind<T, V>(keypath: WritableKeyPath<T, ImplicitlyUnwrappedOptional<V>>) {
}

Unfortunately the documentation says that ImplicitlyUnwrappedOptional is deprecated. 不幸的是,文档说不推荐使用ImplicitlyUnwrappedOptional However, it is not marked as deprecated with the @available attribute. 但是,它未使用@available属性标记为已弃用。

I'm hesitant to use a type that the docs say are deprecated, but I can find no other way to accomplish what I need. 我犹豫是否使用文档所说的不赞成的类型,但我找不到其他方法来完成我需要的东西。

  1. Is there another way to get the implicitly wrapped generic Value type from a WritableKeyPath when its type is WritableKeyPath<T, V!> ? 当其类型为WritableKeyPath<T, V!>时,是否有另一种方法可以从WritableKeyPath获取隐式包装的泛型Value类型?
  2. Will ImplicitlyUnwrappedOptional be removed at some point? ImplicitlyUnwrappedOptional会在某些时候删除吗?

Is there another way to get the implicitly wrapped generic Value type from a WritableKeyPath when its type is WritableKeyPath<T, V!> ? 当其类型为WritableKeyPath<T, V!>时,是否有另一种方法可以从WritableKeyPath获取隐式包装的泛型Value类型?

Not that I'm aware of. 不是我知道的。 Really the problem here is that \\Something.s shouldn't be a WritableKeyPath<T, V!> . 真正的问题是\\Something.s 应该是WritableKeyPath<T, V!> That should be illegal under the rules set out by SE-0054 (IUOs are attributes on declarations; they're not actual types that can satisfy generic placeholders). 根据SE-0054规定的规则,这应该是非法的(IUO是声明的属性;它们不是可以满足通用占位符的实际类型)。

Instead, \\Something.s should be a WritableKeyPath<T, V?> , so really your original code ought to compile. 相反, \\Something.s应该是WritableKeyPath<T, V?> ,所以你的原始代码应该编译。 This issue has been filed as a bug here . 此问题已在此处作为错误提交

Will ImplicitlyUnwrappedOptional be removed at some point? ImplicitlyUnwrappedOptional会在某些时候删除吗?

Yes, this is set out by SE-0054 : 是的,这是由SE-0054提出的

Because IUOs are an attribute on declarations rather than on types, the ImplicitlyUnwrappedOptional type, as well as the long form ImplicitlyUnwrappedOptional<T> syntax, is removed. 因为IUO是声明而不是类型的属性,所以删除了ImplicitlyUnwrappedOptional类型以及长形式ImplicitlyUnwrappedOptional<T>语法。 Types with nested IUOs are no longer allowed. 不再允许具有嵌套IUO的类型。 This includes types such as [Int!] and (Int!, Int!) . 这包括[Int!](Int!, Int!)

However the type-checker implementation for this wasn't fully implemented for Swift 4, which is why you're still able to use ImplicitlyUnwrappedOptional as a type in order to work around your problem. 但是,对于Swift 4来说,类型检查器实现并没有完全实现,这就是为什么你仍然可以使用ImplicitlyUnwrappedOptional作为一种类型来解决你的问题。 It has been implemented for Swift 5 though , so your workaround will no longer compile on its release. 它已经为Swift 5实现了 ,因此您的解决方法将不再在其发布时进行编译。

Although hopefully the IUO key path bug will have been fixed by then. 虽然希望IUO密钥路径错误将被修复。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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