You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

访问未赋值的隐式解包可选类型未崩溃,原因是什么?

为什么访问user?.token没有触发崩溃?

咱们来拆解一下你遇到的这个问题,核心原因在于Swift中隐式解包可选类型(Implicitly Unwrapped Optional, IUO)在可选链中的行为和直接访问时完全不一样

1. 先搞清楚隐式解包可选的本质

你定义的tokenString!,也就是隐式解包可选。它的本质还是一个可选类型,只是编译器允许你在直接访问时省略解包操作——这只是语法糖而已。当你直接访问它(比如user!.token)时,编译器会自动帮你加上强制解包,此时如果tokennil就会触发崩溃。

但在可选链(?.)的上下文里,隐式解包可选会被当作普通的可选类型(String?)来处理,不会触发强制解包操作。

2. 你的场景具体发生了什么

你声明了var user: User?,并给非token的属性赋值,此时user是一个非nil的可选实例,但它的token属性是nil(因为你没赋值,而隐式解包可选的默认值就是nil)。

当你用user?.token访问时:

  • 首先,?.会先检查user是否为nil,这里user有值,所以继续访问token
  • 但因为是在可选链中,tokenString!会被降级为String?,Swift不会强制解包它,只是返回nil,而不是触发崩溃。

3. 对比会崩溃的场景

如果换成强制解包user后直接访问token,就会触发崩溃:

let token = user!.token // 这里会崩溃,因为强制解包了nil的token

因为user!强制解包得到User实例后,访问token就会触发隐式解包的强制操作,此时tokennil,自然会崩溃。

总结

可选链的设计就是为了安全地逐层访问可选属性/方法,它会把所有参与的可选类型(包括隐式解包可选)都当作普通可选处理,不会进行强制解包。所以user?.token只会返回nil,而不会崩溃。

内容的提问来源于stack exchange,提问作者nsd32

火山引擎 最新活动