Denis
Denis

Reputation: 199

'let' property may not be initialized directly; use "self.init(...)" or "self = ..." instead

I want to try to write a default init in a protocol extension, so I did this:

protocol P {
    var data: [AnyHashable: Any] { get }
    init(_ s: String)
}

extension P {
    init(_ s: String) {
        self.data = ["s": s]
    }
}

But I'm getting this error:

'let' property 'data' may not be initialized directly; use "self.init(...)" or "self = ..." instead

I have no idea what it means. Thanks for your help!

Upvotes: 8

Views: 13243

Answers (2)

Vyacheslav
Vyacheslav

Reputation: 27211

import PlaygroundSupport

protocol P {
    var data: [AnyHashable: Any] { get }
    var _data: [AnyHashable: Any] { get set }
    static func generator(_ s: String) -> P
    init()
}

extension P {
    static func generator(_ s: String) -> P {
        var p = self.init()
        p._data = ["s": s]
        return p
    }
}

class A: P {
    required init() { }
    var data: [AnyHashable : Any] {
        return _data
    }
    var _data: [AnyHashable : Any] = [:]
}

let a = A.generator("some")
print(a.data)

PlaygroundPage.current.finishExecution()

I think this is the closest code you want. The problem is that _data is shared by other classes.

Upvotes: 1

vadian
vadian

Reputation: 285072

The error says that the variable cannot be initialized in the protocol extension because it's declared as constant { get }

But even if you declare the variable { get set } you can't use the init method anyway without a constraint to a concrete type or an associated type.

Upvotes: 8

Related Questions