看看以下代码:
struct Something {
var s: String! // Implicitly Unwrapped Optional
}
func bind<T, V>(keyPath: WritableKeyPath<T, V?>) {
}
bind(\Something.s)
上面的代码无法编译。如果我们将bind
的签名更改为bind<T, V>(keyPath: WritableKeyPath<T, V>)
,那么会编译,但问题是V
的类型是String!
而我需要获取基础类型,在本例中为String
。
我们可以解决以下问题:
func bind<T, V>(keypath: WritableKeyPath<T, ImplicitlyUnwrappedOptional<V>>) {
}
不幸的是,文档说不推荐使用ImplicitlyUnwrappedOptional
。但是,它未使用@available
属性标记为已弃用。
我犹豫是否使用文档所说的类型已被弃用,但我找不到其他方法来实现我所需要的。
Value
时,是否有另一种方法可以从WritableKeyPath
获取隐式包装的通用WritableKeyPath<T, V!>
类型?ImplicitlyUnwrappedOptional
吗?答案 0 :(得分:3)
当其类型为
Value
时,是否有另一种方法可以从WritableKeyPath
获取隐式包装的通用WritableKeyPath<T, V!>
类型?
不是我意识到的。这里的问题真的是\Something.s
不应该是WritableKeyPath<T, V!>
。根据{{3}}规定的规则,这应该是非法的(IUO是声明的属性;它们不是可以满足通用占位符的实际类型)。
相反,\Something.s
应该是WritableKeyPath<T, V?>
,所以您的原始代码应该编译。此问题一直是SE-0054。
是否会在某个时候删除
ImplicitlyUnwrappedOptional
?
是的,这由filed as a bug here
列出由于IUO是声明而不是类型的属性,因此会删除
ImplicitlyUnwrappedOptional
类型以及长格式ImplicitlyUnwrappedOptional<T>
语法。不再允许具有嵌套IUO的类型。其中包括[Int!]
和(Int!, Int!)
等类型。
但是,对于Swift 4,这种类型检查器的实现并未完全实现,这就是为什么您仍然可以使用ImplicitlyUnwrappedOptional
作为类型来解决问题的原因。 SE-0054,因此您的解决方法将不再在其发布时进行编译。
虽然希望IUO密钥路径错误可以在那时修复。