61

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!).

Community
  • 1
  • 1
Artem Abramov
  • 4,701
  • 4
  • 27
  • 38
  • 1
    Have you read "If Statements and Forced Unwrapping" of "The Basics" chapter of [Swift Language Guide](https://developer.apple.com/library/prerelease/ios/documentation/swift/conceptual/swift_programming_language)? – Kreiri Jun 18 '14 at 13:21
  • 1
    2Kreiri: Thank you, I just reread this and the following chapter from the book. There discussed variable that declared `var s1: Type?` and unwrapping this variable with constructions like `if let unwrapped = s1! {}`, but that's not what I'm asking about. – Artem Abramov Jun 18 '14 at 13:31
  • One more possible duplicate even though it's already closed: [In Apple Swift, in what case(s) would I not want an implicitly unwrapped optional?](http://stackoverflow.com/questions/24272781/in-apple-swift-in-what-cases-would-i-not-want-an-implicitly-unwrapped-optiona/24272879#24272879) – rickster Jun 18 '14 at 13:35
  • @ArtemAbramov: "Implicitly Unwrapped Optionals" in the Swift book explains the `var forcedStr: String!` syntax. – Martin R Jun 18 '14 at 13:36

1 Answers1

89

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.

BJ Homer
  • 48,806
  • 11
  • 116
  • 129