Can't make an escaping closure argument optional?

Hi All.

It seems that if you have an escaping closure argument, you can’t make it optional. Am I right?
    init (
        owner:AnyObject,
        handler:@escaping (HXObserverNotification)->Void
        ) {
        self.owner = owner
        self.handler = handler
    }

You could try this:
    init (
        owner:AnyObject,
        handler:@escaping ((HXObserverNotification)->Void)?
        ) {
        self.owner = owner
        self.handler = handler
    }
You get “@escaping attribute only applies to function types”

Or you could try this:
    init (
        owner:AnyObject,
        handler:(@escaping (HXObserverNotification)->Void)?
        ) {
        self.owner = owner
        self.handler = handler
    }
You get “@escaping attribute may only be used in function parameter position”

-Kenny

If you remove the @escaping you'll notice it doesn't complain about a non-escaping closure escaping.
I could be wrong, but I believe that's because using it as an associated value forces it to escape on the calling side.

func esc(_ x: @escaping () -> ()) {
    x()
}
func noesc(_ x: () -> ()) {
    x()
}

func foo() {
    noesc {
        print(owner) // compiles
    }
    esc {
        print(owner) // error: requires explicit 'self.'…
    }
    Optional<()->()>.some {
        print(owner) // error: requires explicit 'self.'…
    }
}

···

On Jan 5, 2018, at 11:48 AM, Kenny Leung via swift-users <swift-users@swift.org> wrote:

Hi All.

It seems that if you have an escaping closure argument, you can’t make it optional. Am I right?
    init (
        owner:AnyObject,
        handler:@escaping (HXObserverNotification)->Void
        ) {
        self.owner = owner
        self.handler = handler
    }

You could try this:
    init (
        owner:AnyObject,
        handler:@escaping ((HXObserverNotification)->Void)?
        ) {
        self.owner = owner
        self.handler = handler
    }
You get “@escaping attribute only applies to function types”

Or you could try this:
    init (
        owner:AnyObject,
        handler:(@escaping (HXObserverNotification)->Void)?
        ) {
        self.owner = owner
        self.handler = handler
    }
You get “@escaping attribute may only be used in function parameter position”

-Kenny

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

Because it’s being assigned to an ivar, it’s forced to be escaping, or so the compiler tells me.

-Kenny

···

On Jan 5, 2018, at 12:04 PM, Kevin Nattinger <swift@nattinger.net> wrote:

If you remove the @escaping you'll notice it doesn't complain about a non-escaping closure escaping.
I could be wrong, but I believe that's because using it as an associated value forces it to escape on the calling side.

func esc(_ x: @escaping () -> ()) {
    x()
}
func noesc(_ x: () -> ()) {
    x()
}

func foo() {
    noesc {
        print(owner) // compiles
    }
    esc {
        print(owner) // error: requires explicit 'self.'…
    }
    Optional<()->()>.some {
        print(owner) // error: requires explicit 'self.'…
    }
}

On Jan 5, 2018, at 11:48 AM, Kenny Leung via swift-users <swift-users@swift.org <mailto:swift-users@swift.org>> wrote:

Hi All.

It seems that if you have an escaping closure argument, you can’t make it optional. Am I right?
    init (
        owner:AnyObject,
        handler:@escaping (HXObserverNotification)->Void
        ) {
        self.owner = owner
        self.handler = handler
    }

You could try this:
    init (
        owner:AnyObject,
        handler:@escaping ((HXObserverNotification)->Void)?
        ) {
        self.owner = owner
        self.handler = handler
    }
You get “@escaping attribute only applies to function types”

Or you could try this:
    init (
        owner:AnyObject,
        handler:(@escaping (HXObserverNotification)->Void)?
        ) {
        self.owner = owner
        self.handler = handler
    }
You get “@escaping attribute may only be used in function parameter position”

-Kenny

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

At the moment an optional closure is considered escaping so you don’t have
to state it using @escaping and as you see you actually can’t. A bug or two
exists against Swift related this and I don’t know their current state.

If after removing @escaping things still fail to compile please post a code
example.

-Shawn

···

On Fri, Jan 5, 2018 at 1:17 PM Kenny Leung via swift-users < swift-users@swift.org> wrote:

Because it’s being assigned to an ivar, it’s forced to be escaping, or so
the compiler tells me.

-Kenny

On Jan 5, 2018, at 12:04 PM, Kevin Nattinger <swift@nattinger.net> wrote:

If you remove the @escaping you'll notice it doesn't complain about a
non-escaping closure escaping.
I could be wrong, but I believe that's because using it as an associated
value forces it to escape on the calling side.

func esc(_ x: @escaping () -> ()) {
    x()
}
func noesc(_ x: () -> ()) {
    x()
}

func foo() {
    noesc {
        print(owner) // compiles
    }
    esc {
        print(owner) // error: requires explicit 'self.'…
    }
    Optional<()->()>.some {
        print(owner) // error: requires explicit 'self.'…
    }
}

On Jan 5, 2018, at 11:48 AM, Kenny Leung via swift-users < > swift-users@swift.org> wrote:

Hi All.

It seems that if you have an escaping closure argument, you can’t make it
optional. Am I right?
    init (
        owner:AnyObject,
        handler:@escaping (HXObserverNotification)->Void
        ) {
        self.owner = owner
        self.handler = handler
    }

You could try this:
    init (
        owner:AnyObject,
        handler:@escaping ((HXObserverNotification)->Void)?
        ) {
        self.owner = owner
        self.handler = handler
    }
You get “@escaping attribute only applies to function types”

Or you could try this:
    init (
        owner:AnyObject,
        handler:(@escaping (HXObserverNotification)->Void)?
        ) {
        self.owner = owner
        self.handler = handler
    }
You get “@escaping attribute may only be used in function parameter
position”

-Kenny

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

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

2 Likes

You are correct! Thanks!

-Kenny

···

On Jan 5, 2018, at 1:24 PM, Shawn Erickson <shawnce@gmail.com> wrote:

At the moment an optional closure is considered escaping so you don’t have to state it using @escaping and as you see you actually can’t. A bug or two exists against Swift related this and I don’t know their current state.

If after removing @escaping things still fail to compile please post a code example.

-Shawn
On Fri, Jan 5, 2018 at 1:17 PM Kenny Leung via swift-users <swift-users@swift.org <mailto:swift-users@swift.org>> wrote:
Because it’s being assigned to an ivar, it’s forced to be escaping, or so the compiler tells me.

-Kenny

On Jan 5, 2018, at 12:04 PM, Kevin Nattinger <swift@nattinger.net <mailto:swift@nattinger.net>> wrote:

If you remove the @escaping you'll notice it doesn't complain about a non-escaping closure escaping.
I could be wrong, but I believe that's because using it as an associated value forces it to escape on the calling side.

func esc(_ x: @escaping () -> ()) {
    x()
}
func noesc(_ x: () -> ()) {
    x()
}

func foo() {
    noesc {
        print(owner) // compiles
    }
    esc {
        print(owner) // error: requires explicit 'self.'…
    }
    Optional<()->()>.some {
        print(owner) // error: requires explicit 'self.'…
    }
}

On Jan 5, 2018, at 11:48 AM, Kenny Leung via swift-users <swift-users@swift.org <mailto:swift-users@swift.org>> wrote:

Hi All.

It seems that if you have an escaping closure argument, you can’t make it optional. Am I right?
    init (
        owner:AnyObject,
        handler:@escaping (HXObserverNotification)->Void
        ) {
        self.owner = owner
        self.handler = handler
    }

You could try this:
    init (
        owner:AnyObject,
        handler:@escaping ((HXObserverNotification)->Void)?
        ) {
        self.owner = owner
        self.handler = handler
    }
You get “@escaping attribute only applies to function types”

Or you could try this:
    init (
        owner:AnyObject,
        handler:(@escaping (HXObserverNotification)->Void)?
        ) {
        self.owner = owner
        self.handler = handler
    }
You get “@escaping attribute may only be used in function parameter position”

-Kenny

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

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