Why create “Implicitly Unwrapped Optionals”, since that implies you know there's a value?

前端 未结 10 1690
深忆病人
深忆病人 2020-11-22 07:30

Why would you create a \"Implicitly Unwrapped Optional\" vs creating just a regular variable or constant? If you know that it can be successfully unwrapped then why create a

相关标签:
10条回答
  • 2020-11-22 08:01

    Consider the case of an object that may have nil properties while it's being constructed and configured, but is immutable and non-nil afterwards (NSImage is often treated this way, though in its case it's still useful to mutate sometimes). Implicitly unwrapped optionals would clean up its code a good deal, with relatively low loss of safety (as long as the one guarantee held, it would be safe).

    (Edit) To be clear though: regular optionals are nearly always preferable.

    0 讨论(0)
  • 2020-11-22 08:02

    If you know for sure, a value return from an optional instead of nil, Implicitly Unwrapped Optionals use to directly catch those values from optionals and non optionals can't.

    //Optional string with a value
    let optionalString: String? = "This is an optional String"
    
    //Declaration of an Implicitly Unwrapped Optional String
    let implicitlyUnwrappedOptionalString: String!
    
    //Declaration of a non Optional String
    let nonOptionalString: String
    
    //Here you can catch the value of an optional
    implicitlyUnwrappedOptionalString = optionalString
    
    //Here you can't catch the value of an optional and this will cause an error
    nonOptionalString = optionalString
    

    So this is the difference between use of

    let someString : String! and let someString : String

    0 讨论(0)
  • 2020-11-22 08:04

    Apple gives a great example in The Swift Programming Language -> Automatic Reference Counting -> Resolving Strong Reference Cycles Between Class Instances -> Unowned References and Implicitly Unwrapped Optional Properties

    class Country {
        let name: String
        var capitalCity: City! // Apple finally correct this line until 2.0 Prerelease (let -> var)
        init(name: String, capitalName: String) {
            self.name = name
            self.capitalCity = City(name: capitalName, country: self)
        }
    }
    
    class City {
        let name: String
        unowned let country: Country
        init(name: String, country: Country) {
            self.name = name
            self.country = country
        }
    }
    

    The initializer for City is called from within the initializer for Country. However, the initializer for Country cannot pass self to the City initializer until a new Country instance is fully initialized, as described in Two-Phase Initialization.

    To cope with this requirement, you declare the capitalCity property of Country as an implicitly unwrapped optional property.

    0 讨论(0)
  • 2020-11-22 08:08

    The rationale of implicit optionals is easier to explain by first looking at the rationale for forced unwrapping.

    Forced unwrapping of an optional (implicit or not), using the ! operator, means you're certain that your code has no bugs and the optional already has a value where it is being unwrapped. Without the ! operator, you would probably just assert with an optional binding:

     if let value = optionalWhichTotallyHasAValue {
         println("\(value)")
     } else {
         assert(false)
     }
    

    which is not as nice as

    println("\(value!)")
    

    Now, implicit optionals let you express having an optional which you expect to always to have a value when unwrapped, in all possible flows. So it just goes a step further in helping you - by relaxing the requirement of writing the ! to unwrap each time, and ensuring that the runtime will still error in case your assumptions about the flow are wrong.

    0 讨论(0)
提交回复
热议问题