FelipeDev.-
FelipeDev.-

Reputation: 3133

Double exclamation !! mark in Swift?

I know the definition for a single exclamation mark, but two?

I was coding today and the compiler "force" me to add one more ! to my sentence:

mySignal.subscribeNext({
        (value: AnyObject!) -> () in
        let list: RACSequence = value["myObject"]!!.rac_sequence
        ...

If I use only one ! mark, the project doesn't compile, giving me the error: "Value of optional type 'AnyObject?' not unwrapped; did you mean to use '!' or '?'?" Then I add one more ! and everything works.

What's the meaning for two exclamation marks in Swift?

Upvotes: 18

Views: 3863

Answers (2)

Rikki Gibson
Rikki Gibson

Reputation: 4337

This is a strange artifact of the use of the AnyObject type instead of an explicit dictionary type. Normally, a monad like Optional (thanks user2864740) implements a bind operation with a signature like Optional<T>.bind(f: T -> Optional<U>) -> Optional<U>.

This makes it so when you access an optional member of an optional value, you don't get a double-optional that you have to unwrap like an onion with each layer of access.

If you do a similar example with an explicit dictionary, you'll find the resulting type to be just a single layer of Optional:

import UIKit

let anyDict: AnyObject? = ["foo" : 34, "bar" : 13]
let anyElement = anyDict?["foo"]
print(anyElement) // Optional(Optional(34))

let dict: [String : Int]? = ["foo" : 34, "bar" : 13]
let element = dict?["foo"]
print(element) // Optional(34)

It's not clear why this is happening with AnyObject, but I don't believe it's the intended behavior.

Upvotes: 7

Dave Wood
Dave Wood

Reputation: 13323

You're storing an AnyObject! in the dictionary, so you're storing an optional as the value. Dictionary subscripts always return an optional of the value you're storing, so you're getting an optional optional, which is why you need two !, to unwrap it twice.

Upvotes: 9

Related Questions