[swift-users] Protocol with instance var that's set on construction, otherwise read-only

Dan Loewenherz dan at lionheartsw.com
Wed Aug 3 05:23:38 CDT 2016


On Wed, Aug 3, 2016 at 3:51 AM, Rick Mann via swift-users <
swift-users at swift.org> wrote:

>
> > On Aug 2, 2016, at 19:06 , Jordan Rose <jordan_rose at apple.com> wrote:
> >
> > I don’t think it makes sense to do this. A protocol cannot control how a
> particular property is implemented (stored or computed), and any conforming
> type must initialize all of its stored properties before returning from its
> own initializer. (You can’t write an initializer in a protocol that doesn’t
> delegate to another initializer because you don’t know what other stored
> properties the conforming type might have.)
> >
> > Given that the protocol can’t control how the property gets initialized,
> it doesn’t make sense to allow the protocol to "set the variable, but only
> in the initializer”.
>
> Really? It seems pretty natural for a conforming type to set a property
> once in the initializer, and it's immutable from then on out. I can do that
> quite cleanly with classes, but there's no way (that I know) to describe
> this using protocols. Ideally, I could just do:
>
> protocol
> Element
> {
>     let uuid: UUID
> }
>
> which implies that all conforming types must initialize that value on
> creation, or provide a getter with let semantics (the latter might be too
> easy to break, and could be disallowed, requiring conforming types to
> create storage for the property and set it in init()).


The compiler only knows as much as you tell it, and when you define a
protocol and set it as { get } only, it's not going to let you set that
property in a protocol extension for a protocol that doesn't expect a
setter. Why or how would the compiler let you?

The solution is to create your init implementation in a concrete type, and
define the let property in there as well. E.g.

protocol Element {
    var uuid: UUID { get }
}

class Item: Element {
    let uuid: UUID

    init(uuid: UUID) {
        self.uuid = uuid
    }
}
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-users/attachments/20160803/35e23de3/attachment.html>


More information about the swift-users mailing list