[英]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. 我犹豫是否使用文档所说的不赞成的类型,但我找不到其他方法来完成我需要的东西。
Value
type from a WritableKeyPath
when its type is WritableKeyPath<T, V!>
? WritableKeyPath<T, V!>
时,是否有另一种方法可以从WritableKeyPath
获取隐式包装的泛型Value
类型? ImplicitlyUnwrappedOptional
be removed at some point? ImplicitlyUnwrappedOptional
会在某些时候删除吗? Is there another way to get the implicitly wrapped generic
Value
type from aWritableKeyPath
when its type isWritableKeyPath<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 formImplicitlyUnwrappedOptional<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.