Edit: The intent of this question was to understand the use of the implicit optional operator "!" in the early UIKit API updates, specifically if a function was declared as returning a type expected to be non optional, why use optional at all, and if it was optional, why not use the optional "?" operator. The semantics of "!" were always clear though.
As time later showed, it was a matter of Apple auditing the API to make the optionality more precise, using ? for truly optional types, and using non optional types when they were in fact non optional. This was a hold-over of the original Objective-C signatures which were often ambiguous.
The swift documentation explains the purpose of the ! unboxing operator on optional types,
var optionalString : String? = "optional"
var regularString: String = optionalString!
but they have used it on type definitions themselves (String!), without an explicit explanation that I can find.
Example:
func takesBang(value:String!) -> String {
if !value {
return "nil value, without the safe syntax"
}
return "This works"
}
var unsafe:String!
takesBang(unsafe) // yields "nil value, without the safe syntax"
The String! type does not force an unboxing of the optional type, but only seems to remove the need for optional syntax (?.). Apple uses this in their own examples, but it seems to only negate the optional safety (pointer) mechanisms.
Can anybody explain the purpose / motivation? This seems generally unsafe as the caller won't have to check or at least think about their value.
The Language Reference states that both, ?
as also !
, when used on var
declarations are only syntactic sugar (meaning they are replaced by the compiler during parsing). They map to Optional<T>
(?) and ImplicitlyUnwrappedOptional<T>
(!) respectively.
While you have to use the if let maybeNil = someVar? { ... }
syntax for variables of type Optional<T>
, you don't have to do so with the implicitly unwrapped optionals (as the name already implies). As the poster in https://stackoverflow.com/a/24071003/1599345 already mentioned, implicitly unwrapped optionals are meant to be used with legacy Objective-C APIs, since those don't provide enough information for Swift.
So as a short recap:
var foo : SomeType? // should be read as var foo : Optional<SomeType>
var bar : SomeType! // should be read as var bar : ImplicitlyUnwrappedOptional<SomeType>
The usage of ?
and !
when working with actual values in variables is actually a mapping that can be read in this way, analogous to the declarations above:
foo?.somemethod() // if let maybeFoo = foo { maybeFoo.somemethod() }
foo!.somemethod() /* # Yeah I know for sure, that this is NOT nil ever ever… just call `somemethod` and kill me at runtime if it doesn't work out.
It is generally unsafe, but is used for imported Objective-C APIs, which are already unsafe in that way and don't expose enough information to decide whether they should be Optional or non-Optional.
In non-imported APIs, I wouldn't expect it to be used much.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With