Default init


« Building on our Foundation

List map/flatMap »

I just learned something I should have known but didn't and I want to share it with you.

A while back we looked at turning the free function implementation of IntSet into a struct.

We started with something like this.

struct IntSet { let contains: (Int) -> Bool }

This includes a property named contains and a default init() that accepts contains.

I wanted to add a way of constructing a set from a range. So I wanted to add this to IntSet.

struct IntSet { let contains: (Int) -> Bool init(withRangeFrom lower: Int, to upper: Int) { contains = {x in (x >= lower) && (x <= upper) } } }

The problem with this is that it prevents the default init from being generated. So we had to explicitly insert the default init like this.

struct IntSet { let contains: (Int) -> Bool init(contains: @escaping (Int) -> Bool) { self.contains = contains } init(withRangeFrom lower: Int, to upper: Int) { contains = {x in (x >= lower) && (x <= upper) } } }

or did we....

If we instead add our additional init in an extension then the automatically generated one is still provided.

struct IntSet { let contains: (Int) -> Bool } extension IntSet { init(withRangeFrom lower: Int, to upper: Int) { contains = {x in (x >= lower) && (x <= upper) } } }

Much nicer.