p42. (PDF)

On page 42 you write: “As we warned, defining this initializer has caused the automatic one to vanish, causing an error in the playground.”

Is this true, it does raise a compile error, but has the automatic initialiser vanished? Is the compile error not due to your having defined an initialiser without parameters, and if so, why then do you suggest you might expect to pass in arguments when initialising an instance?

You go on to say: “Before continuing, let’s make an improvement. As the Vector structure stands, its two initializers have independent code paths. It would be better to have them use one code path by having the parameterless initializer call the initializer which takes both x and y.”

Is it good practice to have two initialisers in this example, and in any event, would the following not suffice?

  init() {
    (x = 0, y = 0)
  }

I am still considering what “code paths” might be. It sounds interesting.

Kind regards.

-u

That initializers have independent code paths means one intializer does not rely on (by invoking or delegating to) other initializer.

Some examples.

Initializers have independent code paths - parameterless initializer does not rely on other initializer:

struct Vector: Printable
{
    var x: Double
    var y: Double
    
    init () {
        x = 0
        y = 0
    }
    
    init (x:Double, y:Double) {
        self.x = x
        self.y = y
    }
    
    func dotProduct (v:Vector) -> Double {
        return x * v.x + y * v.y;
    }

    // Conform to Printable protocol
    var description: String {
        return "Vector (\(x), \(y))"
    }
}

Initializers have dependent code paths - parameterless initializer relies on other initializer:

struct Vector: Printable
{
    var x: Double
    var y: Double
    
    init () {
        // delegate
        self.init (x:0, y:0)
    }
    
    init (x:Double, y:Double) {
        self.x = x
        self.y = y
    }
    
    func dotProduct (v:Vector) -> Double {
        return x * v.x + y * v.y;
    }

    // Conform to Printable protocol
    var description: String {
        return "Vector (\(x), \(y))"
    }
}
let v1 = Vector ()
let v2 = Vector (x:3, y:5.7)

println ("v1 = \(v1)")
println ("v2 = \(v2)")

Thanks for taking the time to explain. It isn’t clear why we have two initialisers, at least not until reaching the section on classes, and even then . . . it seems tortured.

Having looked at my code again, I now see what I did. Pesky colons ;]