Question

While trying to implement the "experiment" on page 35 of the Swift programming guide I get a very strange error in the Xcode playground. In the pokerDeck method, on the line beginning with let card... in the innermost loop, I get the error Value of optional type 'Rank?' not unwrapped. How/why is Rank optional?

struct Card {
    var rank : Rank
    var suit : Suit
    init(rank : Rank, suit : Suit) {
        self.rank = rank
        self.suit = suit
    }
    func pokerDeck() -> Card[] {
        let suits = [Suit.Spades, Suit.Clubs, Suit.Hearts, Suit.Diamonds]
        var deck = Card[]()
        for suit in suits {
            for r in 1 ... 13 {
                let card = Card(rank: Rank.fromRaw(r), suit: suit) // ERROR
                deck += card
            }
        }
        return deck
    }
}

The suggested fix by Xcode is to add a !

let card = Card(rank: Rank.fromRaw(r)!, suit: suit)

Which makes the problem even murkier.

Was it helpful?

Solution

The fromRaw() method of an Enum doesn't know what you will pass to it – it can't know if it will succeed on every call – so they designed that method with a return type of Rank? (the return type is an optional)

the ! operator (known as forced unwrapping) forces an optional to be converted into an Enum (and will cause an error if it is nil)

OTHER TIPS

Your problem is that fromRaw returns an optional value. The suggested fix is correct if you're sure all raw values you pass will have an enum value.

the fromRaw() method of an enum returns an optional of the type because there is no guarantee that there is a value for every raw value.

In swift, certain functions return optional wrapped types. In this case, the fromRaw() function returns an optional wrapped enum.

When you know that the type will always be present, declare the var with an exclamation mark (!). This will automatically unwrap the optional to either be used as desired or a runtime error if nil.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top