As per Apple docs, optional chaining is the following:
You specify optional chaining by placing a question mark (?) after the optional value on which you wish to call a property, method or subscript if the optional is non-nil. ... optional chaining fails gracefully when the optional is nil ...
My interpretation of this is that a construction as the following is optional chaining:
someMasterObject.possiblyNilHandler?.handleTheSituation()
...and that the above line would call the handleTheSituation method if the handler is not nil, and fails gracefully (line skipped) if the handler is nil.
However almost all examples I see of optional chaining use the "if let" construction, as per:
if let handler = someMasterObject.possiblyNilHandler{
handler.handleTheSituation()
}
In fact, the documentation and examples I have found on the net make such heavy use of the "if let" construction in relation to optional chaining that it seems as if that IS optional chaining.
Am I correct, however, in assuming that my first example is a supported use of optional chaining and that the if let construction is another construction using (or being intimately tied to) optional chaining?
The conclusion is correct - let
is an independent, but useful, construct. In context it introduces a binding only within the if-body and executes the if-body only if the bound value is not-nil. (Technically it unwraps an optional binding.)
let
does not affect how the expression on the right (with or without chaining) is handled. For instance, if someMasterObject
were optional/nil it would fail and not "chain" - even with let
.
When one or the other (or both) is more "correct" depends on the situation: eg. what is being chained and what the corrective action should be.
For instance, if someMasterObject
could be nil, we might have the following which uses both chaining and let
. Also note how the return value matters and is not simply discarded or "nil on failure":
if let handler = someMasterObject?.possiblyNilHandler{
return handler.handleTheSituation()
} else {
return FAILED_TO_CALL
}
Then compare it with a non-equivalent chained form, which would only return nil
in the failed-to-call case, but nil might be a valid return value from handleTheSituation
!
return someMasterObject?.possiblyNilHandler?.handleTheSituation()
On the other hand, do consider that there is always direct translation of chaining to nested if-let statements:
result_of_expression = someMasterObject?.possiblyNilHandle?.handleTheSituation()
if let master = someMasterObject {
if let handler = master.possiblyNilHandler {
result_of_expression = handler.handleTheSituation()
} else {
result_of_expression = nil
}
} else {
result_of_expression = nil
}
Collected from the Internet
Please contact [email protected] to delete if infringement.
Comments