Search code examples
arraysswiftlazy-initialization

Array with lazy elements


I was wondering if there is a construct in the Swift 3 programming language that allows me to store some objects in an array, but initialize each element in this array lazily.

Imagine this example class:

class A {
    let test = "hello"
    let test2 = 2.0
}

Now I want to store an array of 'A' objects in an array of another class, like this:

class B {
    var lazy(?) array: [A] = {
        // Some code to initialize the element being accessed
    }()
}

If I access any element now, it would be cool if it is initialized just when I am accessing it, so lazily

print(B.array[1].test) (element at index one is now initialized)

Is this possible?


Solution

  • You could use a lazy backing storage for A that is instantiated at first access, e.g.:

    class Astorage {
        /* ... lots of ... */
        let id: Int
        var foo: String = "bar"
        init(_ id: Int) {
            self.id = id
            print("Initializing backing storage for A with id \(id)")
            // ...
        }
    }
    
    class A {
        private let id: Int
        lazy var storage: Astorage = Astorage(self.id)
        init(_ id: Int) {
            self.id = id
        }
    }
    
    class B {
        var array: [A]
        init (_ array: [A]) {
            self.array = array
        }
    }
    
    let b = B((1...5).map(A.init))
    
    b.array[2].storage.foo = "foo"
    // Initializing backing storage for A with id 3
    
    b.array[4].storage.foo = "bax"
    // Initializing backing storage for A with id 5