Conforming to the protocol requirements with implicitly unwrapped optional


(Anton Bronnikov) #1

Hi All,

If I have a protocol with a property requirement such as:

protocol Foo {
    var value: Int { get }
}

.. and I need to conform to it using an implicitly unwrapped optional like:

struct Bar : Foo {
    let value: Int! = nil
}

.. then the compiler fails with an error:

Playground execution failed: error: scratchpad.playground:5:8: error: type 'Bar' does not conform to protocol 'Foo'
struct Bar : Foo {
       ^

scratchpad.playground:2:9: note: protocol requires property 'value' with type 'Int'; do you want to add a stub?
    var value: Int { get }
        ^

scratchpad.playground:6:9: note: candidate has non-matching type 'Int!'
    let value: Int! = nil
        ^
Technically, I understand why the error, and currently work around it with a cumbersome:

struct Bar : Foo {
    var value: Int { return _value! }
    let _value: Int? = nil
}

However, I keep wondering - would it not be making sense to accept implicitly unwrapped optionals as a conformance to be base-type requirements? It sort of works just like that in all other parts of the language.

Or in other words, is this by design, or should I probably create an issue for this?

Thank you.
Cheers,
Anton

P.S. The example is oversimplified for the sake of clarity, in practice the property just has to be an optional - implicitly unwrapped or not - because it’s a part of the composite that holds unowning reference to its container object.


(Zhao Xin) #2

Why you have to use `unwrapped optional` at the first place? If you have to
use it, it means it could be nil. So it won't conform the protocol, which
requires the `value` never nil.

Zhaoxin

···

On Mon, May 29, 2017 at 12:37 PM, Anton Bronnikov via swift-users < swift-users@swift.org> wrote:

Hi All,

If I have a protocol with a property requirement such as:

protocol Foo {
    var value: Int { get }
}

.. and I need to conform to it using an implicitly unwrapped optional like:

struct Bar : Foo {
    let value: Int! = nil
}

.. then the compiler fails with an error:

*Playground execution failed: error: scratchpad.playground:5:8: error:
type 'Bar' does not conform to protocol 'Foo'*
*struct Bar : Foo {*
* ^*

*scratchpad.playground:2:9: note: protocol requires property 'value' with
type 'Int'; do you want to add a stub?*
* var value: Int { get }*
* ^*

*scratchpad.playground:6:9: note: candidate has non-matching type 'Int!'*
* let value: Int! = nil*
* ^*

Technically, I understand why the error, and currently work around it with
a cumbersome:

struct Bar : Foo {
    var value: Int { return _value! }
    let _value: Int? = nil
}

However, I keep wondering - would it not be making sense to accept
implicitly unwrapped optionals as a conformance to be base-type
requirements? It sort of works just like that in all other parts of the
language.

Or in other words, is this by design, or should I probably create an issue
for this?

Thank you.
Cheers,
Anton

P.S. The example is oversimplified for the sake of clarity, in practice
the property just has to be an optional - implicitly unwrapped or not -
because it’s a part of the composite that holds unowning reference to its
container object.

_______________________________________________
swift-users mailing list
swift-users@swift.org
https://lists.swift.org/mailman/listinfo/swift-users


(Anton Bronnikov) #3

Like I mentioned, it is necessary to use optional, but it can not be nil. Consider the following example where I have to use an optional in order to break retention cycle:

protocol Container : class {
    var component: Component { get }
}

class ConcreteContainer : Container {
    var component: Component! = nil
    init() {
        component = Component(container: self)
    }
}

class Component {
    unowned let container: Container
    init(container: Container) {
        self.container = container
    }
}

Playground execution failed: error: scratchpad.playground:5:7: error: type 'ConcreteContainer' does not conform to protocol 'Container'
class ConcreteContainer : Container {
      ^

scratchpad.playground:2:9: note: protocol requires property 'component' with type 'Component'; do you want to add a stub?
    var component: Component { get }
        ^

scratchpad.playground:6:9: note: candidate has non-matching type 'Component!'
    var component: Component! = nil
        ^

Cheers,
Anton

P.S. Declaring protocol as

protocol Container : class {
    var component: Component! { get }
}

.. would also work of course, but my question is not about how to move forward, rather about whether such setup is deliberate.

···

On 29 May 2017, at 08:20, Zhao Xin <owenzx@gmail.com> wrote:

Why you have to use `unwrapped optional` at the first place? If you have to use it, it means it could be nil. So it won't conform the protocol, which requires the `value` never nil.

Zhaoxin

On Mon, May 29, 2017 at 12:37 PM, Anton Bronnikov via swift-users <swift-users@swift.org <mailto:swift-users@swift.org>> wrote:
Hi All,

If I have a protocol with a property requirement such as:

protocol Foo {
    var value: Int { get }
}

.. and I need to conform to it using an implicitly unwrapped optional like:

struct Bar : Foo {
    let value: Int! = nil
}

.. then the compiler fails with an error:

Playground execution failed: error: scratchpad.playground:5:8: error: type 'Bar' does not conform to protocol 'Foo'
struct Bar : Foo {
       ^

scratchpad.playground:2:9: note: protocol requires property 'value' with type 'Int'; do you want to add a stub?
    var value: Int { get }
        ^

scratchpad.playground:6:9: note: candidate has non-matching type 'Int!'
    let value: Int! = nil
        ^
Technically, I understand why the error, and currently work around it with a cumbersome:

struct Bar : Foo {
    var value: Int { return _value! }
    let _value: Int? = nil
}

However, I keep wondering - would it not be making sense to accept implicitly unwrapped optionals as a conformance to be base-type requirements? It sort of works just like that in all other parts of the language.

Or in other words, is this by design, or should I probably create an issue for this?

Thank you.
Cheers,
Anton

P.S. The example is oversimplified for the sake of clarity, in practice the property just has to be an optional - implicitly unwrapped or not - because it’s a part of the composite that holds unowning reference to its container object.

_______________________________________________
swift-users mailing list
swift-users@swift.org <mailto:swift-users@swift.org>
https://lists.swift.org/mailman/listinfo/swift-users


(Zhao Xin) #4

You can try this.

protocol Container : class {

    var component: Component { get }

}

class ConcreteContainer : Container {

    lazy var component: Component = { return Component(container: self) }()

}

class Component {

    unowned let container: Container

    init(container: Container) {

        self.container = container

    }

}

Zhaoxin

···

On Mon, May 29, 2017 at 11:48 PM, Anton Bronnikov <anton.bronnikov@me.com> wrote:

Like I mentioned, it is necessary to use optional, but it can not be nil.
Consider the following example where I have to use an optional in order to
break retention cycle:

protocol Container : class {
    var component: Component { get }
}

class ConcreteContainer : Container {
    var component: Component! = nil
    init() {
        component = Component(container: self)
    }
}

class Component {
    unowned let container: Container
    init(container: Container) {
        self.container = container
    }
}

*Playground execution failed: error: scratchpad.playground:5:7: error:
type 'ConcreteContainer' does not conform to protocol 'Container'*
*class ConcreteContainer : Container {*
* ^*

*scratchpad.playground:2:9: note: protocol requires property 'component'
with type 'Component'; do you want to add a stub?*
* var component: Component { get }*
* ^*

*scratchpad.playground:6:9: note: candidate has non-matching type
'Component!'*
* var component: Component! = nil*
* ^*

Cheers,
Anton

P.S. Declaring protocol as

protocol Container : class {
    var component: Component! { get }
}

.. would also work of course, but my question is not about how to move
forward, rather about whether such setup is deliberate.

On 29 May 2017, at 08:20, Zhao Xin <owenzx@gmail.com> wrote:

Why you have to use `unwrapped optional` at the first place? If you have
to use it, it means it could be nil. So it won't conform the protocol,
which requires the `value` never nil.

Zhaoxin

On Mon, May 29, 2017 at 12:37 PM, Anton Bronnikov via swift-users < > swift-users@swift.org> wrote:

Hi All,

If I have a protocol with a property requirement such as:

protocol Foo {
    var value: Int { get }
}

.. and I need to conform to it using an implicitly unwrapped optional
like:

struct Bar : Foo {
    let value: Int! = nil
}

.. then the compiler fails with an error:

*Playground execution failed: error: scratchpad.playground:5:8: error:
type 'Bar' does not conform to protocol 'Foo'*
*struct Bar : Foo {*
* ^*

*scratchpad.playground:2:9: note: protocol requires property 'value' with
type 'Int'; do you want to add a stub?*
* var value: Int { get }*
* ^*

*scratchpad.playground:6:9: note: candidate has non-matching type 'Int!'*
* let value: Int! = nil*
* ^*

Technically, I understand why the error, and currently work around it
with a cumbersome:

struct Bar : Foo {
    var value: Int { return _value! }
    let _value: Int? = nil
}

However, I keep wondering - would it not be making sense to accept
implicitly unwrapped optionals as a conformance to be base-type
requirements? It sort of works just like that in all other parts of the
language.

Or in other words, is this by design, or should I probably create an
issue for this?

Thank you.
Cheers,
Anton

P.S. The example is oversimplified for the sake of clarity, in practice
the property just has to be an optional - implicitly unwrapped or not -
because it’s a part of the composite that holds unowning reference to its
container object.

_______________________________________________
swift-users mailing list
swift-users@swift.org
https://lists.swift.org/mailman/listinfo/swift-users