There are three way to declare a property in Swift:
var optStr: String? var normStr: String = "normStr" var exactStr: String!
The first one is property with an optional
type, a type that can contain either nil or the String in our case. The second one is a property that always contain the String. It should be initialized in init or in the declaration.
But what about the third way?
var exactStr: String!
I made some experiments in the playground, and it turned out that a function that takes type?
can take both type
, type?
and type!
variables as an argument:
var optStr: String? var normStr: String var forcedStr: String! func printStr(str: String?) { println("str: \(str)") } printStr(optStr) //prints: "str: nil" //printStr(normStr) //doesn't compile as not initialized printStr(forcedStr) //prints: "str: nil" optStr = "optStr"; normStr = "normStr"; forcedStr = "forcedStr" printStr(optStr) //prints "str: optStr" printStr(normStr) //prints "str: normStr" printStr(forcedStr) //prints "str: forcedStr"
So why and when should I use type!
?
Update: this is not a duplicate of What does an exclamation mark mean in the Swift language?. I'm not asking about unwrapping a variable: I'm asking about declaring
a property with an exclamation point (Type!
).
Swift uses exclamation marks to signal both force unwrapping of optionals and explicitly unwrapped optionals.
In Javascript, the exclamation mark (“!”) symbol, called a “bang,” is the logical “not” operator. Placed in front of a boolean value it will reverse the value, returning the opposite.
It's a variable of type "implicitly-unwrapped optional String". Essentially, every access of implicitStr
is treated as if it were written implicitStr!
(thus unwrapping the value).
This, of course, will cause a crash if the value is nil. You can still test the implicit optional via if implicitStr != nil
, or use it in optional chaining as var foo = implicitStr?.uppercaseString
. So you can still use it just as safely as a normal optional; it's just biased toward the case where the value is not nil.
Implicitly-unwrapped optionals are quite useful in cases where the value may not be present at initialization, but are set early and unlikely to become nil again. (For example, a variable you set in -awakeFromNib might reasonably be an implicitly-unwrapped optional.)
Further, since Objective-C methods can return both nil and object types, their return values cannot be modeled as non-optional. To avoid requiring liberal use of forced unwrapping whenever dealing with Cocoa APIs, though, the parameters and return types of Cocoa APIs are usually represented as implicitly-unwrapped optionals.
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