当我找到这个时,我正在审查前同事的代码:
if task != nil {
// why is "?" here?
task?.cancel()
task = nil
}
task
被声明为可选。
我想在那时任务不能 nil 了。那么开发人员为何会提出问号呢?我不能插入感叹号吗?
答案 0 :(得分:3)
由于编译器提示,编译器可能会放置?
,而不是您的同事。
相反,您可以使用if let
语句,如下所示:
if let task2 = task {
task2.cancel()
task = nil
}
task
正在调用cancel()
,因此任务可能是nil
,这里我们通过?
通知编译器任务,如果编译器将获取{ {1}}它会在没有崩溃的情况下静静地进行。
答案 1 :(得分:1)
感谢您指出这一点,但取消并未发生变异,
task
是参考类型
您已经提到task
是一种引用类型,因此即使由于在选择性绑定和变异值时发生的复制/绑定,其他答案中显示的可选绑定方法也可以。但请注意,您无需借助可选绑定来覆盖您所显示的代码段中的逻辑,而只需将可选链接和nil
检查合并为一个条件(并且只在条件体内将属性设置为nil
。
// if task is non-nil, cancel it and set it to 'nil'
// if task is already nil, do nothing
if task?.cancel() != nil { task = nil }
答案 2 :(得分:0)
如果您想避免使用问号,请执行以下操作来解开值:if let task = task
。
答案 3 :(得分:0)
您可以使用if let
或guard
解包该选项,然后您不需要?
或!
答案 4 :(得分:0)
您也可以使用Guard语句解包可选
//This will not unwrap the optional. It will remain optional
if task != nil {
task?.cancel() //That is why the compiler added the question mark automatically
}
// This will unwrap the optional variable
guard let task2 = task else {
return
}
// task will be optional but task2 will not
task?.cancel()
task? = nil
task2.cancel()
task2 = nil