4

This is a code sample from The swift programming language ibook:

class Product {
    let name: String!

    init?(name:String) {
        if name.isEmpty { return nil }
        self.name = name
    }
}

It doesn't work unless name is declared as variable instead of a constant. Have there been introduced changes with regard to this issue in Swift 1.2 that I'm not aware of?

nhgrif
  • 61,578
  • 25
  • 134
  • 173
hayordi
  • 119
  • 1
  • 8
  • If you're getting a compiler error or warning, please include that in the question. Also, do you have a link to exactly where you found this code sample? – nhgrif Apr 30 '15 at 00:15

1 Answers1

6

This is due to a change in 1.2 Now, before you return nil from a class's failable initializer, you must set all the properties to valid value. The reason being, the deinit for a class still runs even after the initializer fails, and for correct code, it needs to know that all the properties are validly initialized (also bear in mind the class may be a subclass, and the inheriting class might also rely on valid initialization of properties after its initializer fails).

Implicitly unwrapped optionals are initialized to nil by default – but only if they are declared var. If they are declared with let, then they are immutable and so can only be initialized once, so can’t start off as nil and then change later. Hence, the var version works, but the let version doesn’t.

Note, in the recent update to the Swift book, the code is slightly different – it initializes name first, then fails:

class Product {
     let name: String!
     init?(name: String) {
         self.name = name
         if name.isEmpty { return nil }
     }
}

Also note, structs don’t have the requirement to initialize all their members before failing, only classes (presumably because structs don’t have the complications of deinit or inheritance).

Airspeed Velocity
  • 40,491
  • 8
  • 113
  • 118
  • The Swift book did change. [This answer](http://stackoverflow.com/a/26496022/2792531) has identical code from this question and suggests that the code in this question used to work as-is. – nhgrif Apr 30 '15 at 00:23
  • So it's due to changes introduced in Swift 1.2. Thanks for all answers. Is there an updated version of the book? I didn't find it in iTunes. – hayordi Apr 30 '15 at 00:41
  • You can delete and redownload the Swift book to get the latest, not sure if it is supposed to update automatically or let you re-download without deleting. – Airspeed Velocity Apr 30 '15 at 01:14