1

At the moment, I am getting the following errors when attempting to run the following code: enum case good not found in type Situation? and enum case bad not found in type Situation?

enum Situation: Error {
        case good
        case bad
}

class SituationHandler {
    var situation: Situation!
    static let shared = SituationHandler()
}

class Scenario {

    func handleScenario() {

        let situation = SituationHandler.shared.situation
        switch situation {
        case .good:
            print("All good")
        case .bad:
            print("All bad")
        }

    }
}

If I am using the situation on the SituationHandler as a Implicitly Unwrapped Optional, shouldn't I not receive this complaint? What am I doing wrong?

Thanks for the help to everyone who answers this.

Marcy
  • 4,611
  • 2
  • 34
  • 52
Adam Cooper
  • 867
  • 1
  • 6
  • 23
  • Related: https://stackoverflow.com/questions/39633481/implicitly-unwrapped-optional-assign-in-xcode-8. – Martin R Feb 07 '19 at 19:07

2 Answers2

0

Implicitly unwrapped optionals are still optionals. If they can be used as normal optionals, they will be.

You can enforce unwrapping simply by declaring a non-optional type:

let situation: Situation = SituationHandler().shared.situation

or by adding ! explicitly:

let situation = SituationHandler().shared.situation!

On a side note, note that:

SituationHandler().shared.situation

does not make any sense. shared is always a new instance. To have a singleton, you need:

class SituationHandler {
   var situation: Situation!
   static let shared = SituationHandler()
}

and then:

SituationHandler.shared.situation

Also I would advise to use a default value instead of an IUO:

class SituationHandler {
    var situation: Situation = .bad
    static let shared = SituationHandler()
}
Sulthan
  • 128,090
  • 22
  • 218
  • 270
0

Think of implicitly unwrapped optionals as optionals that can be coerced into non-optionals by the type system. They are still, at the core, optionals. Your code snippet doesn't give the type system any indication that you actually want the non-optional value. You can either explicitly unwrap, or use type inference, to get the unwrapped value. Note that either way results in an unsafe unwrap (and if you have a nil value under there, it'll still crash).

struct SomeObject {

    let iuo: Int! = 3

}

let value1 = SomeObject().iuo
print(type(of: value1)) // Optional<Int>

let value2: Int = SomeObject().iuo
print(type(of: value2)) // Int

let value3 = SomeObject().iuo!
print(type(of: value3)) // Int
Connor Neville
  • 7,291
  • 4
  • 28
  • 44