我有一堂课,我有这样的财产:
var residenceId: Int!
Run Code Online (Sandbox Code Playgroud)
使用Xcode 10和Swift 4.2进行构建时,没有问题。但是,在安装Xcode 11 Beta并转换为Swift 5之后,我得到以下警告:
Implicitly unwrapped property 'residenceId' declared here
Run Code Online (Sandbox Code Playgroud)
在上一节课中,我还具有以下功能:
func jsonDictionary() -> [String : Any] {
return ["residenceId": residenceId]
}
Run Code Online (Sandbox Code Playgroud)
我在这里得到警告
Coercion of implicitly unwrappable value of type 'Int?' to 'Any' does not unwrap optional
Run Code Online (Sandbox Code Playgroud)
我们是否不再被允许使用隐式展开的可选?
编辑:
经过更多研究之后,我开始相信“在这里声明的未包装属性'residenceId'实际上不是警告”,而是一些信息(以灰色标签而不是通常的黄色)以帮助我理解为什么我收到第二个警告。
为了澄清,我的问题是,我们是否不再能够使用“!” 属性上的符号定义一个隐式解开的属性(仅在我们确定它不会为nil时才明显),以便以后避免显式解开它(从而简化代码)。
从 Swift 4 开始,ImplicitlyUnwrappedOptional或者!我们所知道的,它变成了 Optional.
查看:
let a: ImplicitlyUnwrappedOptional<Int> = 1
Run Code Online (Sandbox Code Playgroud)
会吐出错误:
“ImplicitlyUnwrappedOptional”已重命名为“Optional”
因此,如果我们这样做:
let a: Int! = 1
print(type(of: a)) //will print "Optional<Int>"
Run Code Online (Sandbox Code Playgroud)
它仍然Optional<Int>但是向编译器表明它可以隐式解包。
隐式解包是声明的一部分。
...
认为
!是添加的同义词?,它在声明上添加一个标志,让编译器知道声明的值可以隐式解包。
Ref:隐式解包选项的重新实现
如果你这样做:
let a: Int! = 1
let b: Any = a
print(type(of: b)) //prints "Optional<Int>"
Run Code Online (Sandbox Code Playgroud)
它将给出以下警告:
从“Int?”隐式强制的表达式 去任何'
或根据 Xcode 11
'Int?' 类型的隐式不可包装值的强制转换 'Any' 不解包可选
请注意,我们试图Any从 an 中获取一个非可选的,Int?这意味着我们基本上期待 anInt但仅仅通过指定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
Run Code Online (Sandbox Code Playgroud)
!而不是对?程序员有任何实际区别?
! 告诉编译器它可以隐式解包,因此它可以帮助减轻对可选链接的需求。
例子:
和 ?
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)
*/
Run Code Online (Sandbox Code Playgroud)和 !
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)
Run Code Online (Sandbox Code Playgroud)
b.a.n并且b?.a?.n都会Optional<Int>在最后给出一个bor ais nilthenb.a.n会崩溃,因为它隐式解包b并a到达n哪个是Optional<Int>Int而不是Optional<Int>,你会这样做b.a.n!,所以在你的情况下你会这样做:print(residenceId!)得到Int我希望我说得有道理
| 归档时间: |
|
| 查看次数: |
402 次 |
| 最近记录: |