Reputation:
I was reviewing the code of an ex-collegue, when I found this one:
if task != nil {
// why is "?" here?
task?.cancel()
task = nil
}
task
is declared as an optional.
I'm supposing at that point task can't be nil anymore. So why the developer puts a question mark? Couldn't I insert an exclamation mark, instead?
Upvotes: 0
Views: 170
Reputation: 835
You can unwrap the optional using if let
or guard
, then you don't need ?
or !
Upvotes: 0
Reputation: 3657
Due to compiler hint the ?
may be put by the compiler, not your colleague.
Instead, you could use an if let
statement as follows:
if let task2 = task {
task2.cancel()
task = nil
}
The task
is calling cancel()
so that may be task is nil
, here we notify to the compiler by ?
for the task, If the compiler will get nil
it goes silently without crashing.
Upvotes: 3
Reputation: 73186
Thanks for pointing this out but cancel is not mutating and
task
is a reference type
You've mentioned that task
is a reference type, so the optional binding methods show in the other answers will be ok even due to the copying/binding that occurs when optionally binding and mutating a value. Note, however, that you needn't necessarily resort to optional binding to cover the logic in the snippet you've shown, but can instead simply combine the optional chaining and the nil
check within a single conditional (and only setting the property to nil
within the body of the conditional).
// 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 }
Upvotes: 1
Reputation: 1614
You can unwrap optional using Guard statements too
//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
Upvotes: 0
Reputation: 5601
You should unwrap the value by doing: if let task = task
if you want to avoid the question mark.
Upvotes: 0