"Implicitly unwrapped property"警告?
"Implicitly unwrapped property" warning?
我有一个 class 我有一个 属性 像这样:
var residenceId: Int!
使用 Xcode 10 和 Swift 4.2 构建时没有问题。但是,在安装 Xcode 11 Beta 并转换为 Swift 5 后,我收到以下警告:
Implicitly unwrapped property 'residenceId' declared here
后面在class我也有这个功能:
func jsonDictionary() -> [String : Any] {
return ["residenceId": residenceId]
}
这里我得到了警告
Coercion of implicitly unwrappable value of type 'Int?' to 'Any' does not unwrap optional
我们是否不再允许使用隐式解包可选?
编辑:
经过更多的研究,我开始相信 "Implicitly unwrapped property 'residenceId' declared here" 实际上并不是一个警告,而是一些信息(它是灰色标签而不是通常的黄色标签)来帮助我理解为什么我收到第二个警告。
澄清一下,我的问题是我们是否不能再使用“!”属性上的符号定义一个隐式展开的 属性(显然只有当我们确定它不会为 nil 时),以便以后避免显式展开它(从而简化代码)。
自从 Swift 4,我们所知道的 ImplicitlyUnwrappedOptional
或 !
变成了 Optional
。
检查:
let a: ImplicitlyUnwrappedOptional<Int> = 1
会吐出错误:
'ImplicitlyUnwrappedOptional' has been renamed to 'Optional'
所以如果我们这样做:
let a: Int! = 1
print(type(of: a)) //will print "Optional<Int>"
它仍然是 Optional<Int>
,但向编译器表明它可以隐式解包。
Implicit Unwrapping is Part of a Declaration.
...
consider !
to be a synonym for ?
with the addition that it adds a flag on the declaration letting the compiler know that the declared value can be implicitly unwrapped.
Ref: Reimplementation of Implicitly Unwrapped Optionals
现在进入主要问题:
如果你这样做:
let a: Int! = 1
let b: Any = a
print(type(of: b)) //prints "Optional<Int>"
它会给出如下警告:
Expression implicitly coerced from 'Int?' to 'Any'
或根据 Xcode 11
Coercion of implicitly unwrappable value of type 'Int?' to 'Any' does not unwrap optional
请注意,我们试图从 Int?
中得到一个非可选的 Any
,这意味着我们基本上期望 Int
但只是通过指定 Any
它不会 也 展开 Optional
.
它将保持 Optional
,这就是该警告背后的含义。
解决方案:
要优雅地处理此警告,我们可以执行以下任一操作:
let a: Int! = 1
let b: Any? = a
type(of: b) //Optional<Any>.Type
let c: Any! = a
type(of: c) //Optional<Any>.Type
let d: Any = a!
type(of: d) //Int.Type
编辑:(基于 comment)
!
instead of ?
have any practical difference for the programmer?
!
告诉编译器它可以被隐式解包,因此它可以帮助缓解对可选链接的需求。
示例:
和?
class A {
var n: Int? = 1
}
class B {
var a: A? = A()
}
let b: B? = B()
print(b?.a?.n)
/*
but the following won't compile as compiler
will not implicitly unwrap optionals
print(b.a.n)
*/
和!
class A {
var n: Int! = 1
}
class B {
var a: A! = A()
}
let b: B! = B()
print(b.a.n) //compiler will implicitly unwrap `!` similar to print(b!.a!.n)
//also... you can still safely unwrap if you want
print(b?.a?.n)
b.a.n
和 b?.a?.n
都会在末尾给出一个 Optional<Int>
- 当然,如果
b
或 a
是 nil
,那么 b.a.n
会崩溃,因为它隐式展开 b
和 a
以到达n
即 Optional<Int>
- 要获得
Int
而不是 Optional<Int>
,您将执行 b.a.n!
,因此在您的情况下,您将执行:print(residenceId!)
以获得 Int
希望我说得有道理
我有一个 class 我有一个 属性 像这样:
var residenceId: Int!
使用 Xcode 10 和 Swift 4.2 构建时没有问题。但是,在安装 Xcode 11 Beta 并转换为 Swift 5 后,我收到以下警告:
Implicitly unwrapped property 'residenceId' declared here
后面在class我也有这个功能:
func jsonDictionary() -> [String : Any] {
return ["residenceId": residenceId]
}
这里我得到了警告
Coercion of implicitly unwrappable value of type 'Int?' to 'Any' does not unwrap optional
我们是否不再允许使用隐式解包可选?
编辑:
经过更多的研究,我开始相信 "Implicitly unwrapped property 'residenceId' declared here" 实际上并不是一个警告,而是一些信息(它是灰色标签而不是通常的黄色标签)来帮助我理解为什么我收到第二个警告。
澄清一下,我的问题是我们是否不能再使用“!”属性上的符号定义一个隐式展开的 属性(显然只有当我们确定它不会为 nil 时),以便以后避免显式展开它(从而简化代码)。
自从 Swift 4,我们所知道的 ImplicitlyUnwrappedOptional
或 !
变成了 Optional
。
检查:
let a: ImplicitlyUnwrappedOptional<Int> = 1
会吐出错误:
'ImplicitlyUnwrappedOptional' has been renamed to 'Optional'
所以如果我们这样做:
let a: Int! = 1
print(type(of: a)) //will print "Optional<Int>"
它仍然是 Optional<Int>
,但向编译器表明它可以隐式解包。
Implicit Unwrapping is Part of a Declaration.
...
consider
!
to be a synonym for?
with the addition that it adds a flag on the declaration letting the compiler know that the declared value can be implicitly unwrapped.
Ref: Reimplementation of Implicitly Unwrapped Optionals
现在进入主要问题:
如果你这样做:
let a: Int! = 1
let b: Any = a
print(type(of: b)) //prints "Optional<Int>"
它会给出如下警告:
Expression implicitly coerced from 'Int?' to 'Any'
或根据 Xcode 11
Coercion of implicitly unwrappable value of type 'Int?' to 'Any' does not unwrap optional
请注意,我们试图从 Int?
中得到一个非可选的 Any
,这意味着我们基本上期望 Int
但只是通过指定 Any
它不会 也 展开 Optional
.
它将保持 Optional
,这就是该警告背后的含义。
解决方案:
要优雅地处理此警告,我们可以执行以下任一操作:
let a: Int! = 1
let b: Any? = a
type(of: b) //Optional<Any>.Type
let c: Any! = a
type(of: c) //Optional<Any>.Type
let d: Any = a!
type(of: d) //Int.Type
编辑:(基于 comment)
!
instead of?
have any practical difference for the programmer?
!
告诉编译器它可以被隐式解包,因此它可以帮助缓解对可选链接的需求。
示例:
和
?
class A { var n: Int? = 1 } class B { var a: A? = A() } let b: B? = B() print(b?.a?.n) /* but the following won't compile as compiler will not implicitly unwrap optionals print(b.a.n) */
和
!
class A { var n: Int! = 1 } class B { var a: A! = A() } let b: B! = B() print(b.a.n) //compiler will implicitly unwrap `!` similar to print(b!.a!.n) //also... you can still safely unwrap if you want print(b?.a?.n)
b.a.n
和b?.a?.n
都会在末尾给出一个Optional<Int>
- 当然,如果
b
或a
是nil
,那么b.a.n
会崩溃,因为它隐式展开b
和a
以到达n
即Optional<Int>
- 要获得
Int
而不是Optional<Int>
,您将执行b.a.n!
,因此在您的情况下,您将执行:print(residenceId!)
以获得Int
希望我说得有道理