Re-initialize a lazy initialized variable in Swift

前端 未结 7 835
没有蜡笔的小新
没有蜡笔的小新 2020-12-04 11:08

I have a variable that initialized as:

lazy var aClient:Clinet = {
    var _aClient = Clinet(ClinetSession.shared())
    _aClient.delegate = self
    return          


        
7条回答
  •  臣服心动
    2020-12-04 11:37

    EDIT: As per Ben Leggiero's answer, lazy vars can be nilable in Swift 3. EDIT 2: Seems like nilable lazy vars are no more.

    Very late to the party, and not even sure if this will be relevant in Swift 3, but here goes. David's answer is good, but if you want to create many lazy nil-able vars, you will have to write a pretty hefty block of code. I'm trying to create an ADT that encapsulates this behaviour. Here's what I've got so far:

    struct ClearableLazy {
        private var t: T!
        private var constructor: () -> T
        init(_ constructor: @escaping () -> T) {
            self.constructor = constructor
        }
        mutating func get() -> T {
            if t == nil {
                t = constructor()
            }
            return t
        }
        mutating func clear() { t = nil }
    }
    

    You would then declare and use properties like this:

    var aClient = ClearableLazy(Client.init)
    aClient.get().delegate = self
    aClient.clear()
    

    There are things I don't like about this yet, but don't know how to improve:

    • You have to pass a constructor to the initializer, which looks ugly. It has the advantage, though, that you can specify exactly how new objects are to be created.
    • Calling get() on a property every time you want to use it is terrible. It would be slightly better if this was a computed property, not a function, but computed properties cannot be mutating.
    • To eliminate the need to call get(), you have to extend every type you want to use this for with initializers for ClearableLazy.

    If someone feels like picking it up from here, that would be awesome.

提交回复
热议问题