My function has this signature:
func foo(bar: String, baz: ((String) -> ())? = nil)
And now I want to make unecessary to escape self
inside the given closure.
But when I try this:
func foo(bar: String, @noescape baz: ((String) -> ())? = nil)
The compiler complains:
@noescape may only be applied to parameters of function type
Is it possible to use it in optional parameters?
Requirements
If your requirements are the following:
- the
baz
param is a closure
- the
baz
param is marked with @noescape
(because you want to omit self
in the closure code)
- the
baz
param can be omitted during the invocation of foo
Solution
Then you can use the following syntax
func foo(bar: String, @noescape baz: ((String) -> ()) = { _ in } ) {
}
As you can see the main difference from your code is that:
- here
baz
is not an optional type
(but it's an "optional parameter")
- and its default value is an
empty closure
not a nil
value.
Examples
As you requested you can now pass a closure to baz
without the need of using self
class Boo {
let world = "world"
func boo() {
foo("hello") { (something) -> () in
print(world)
}
}
}
And you can also omit the baz
param
class Boo {
let world = "world"
func boo() {
foo("hello")
}
}
Update: using a closure with return type different from Void
In a comment below users TadeasKriz
asked about how to use this approach with a closure having the return value different the Void
.
Here it is the solution
func foo(bar: String, @noescape baz: ((String) -> (Int)) = { _ in return 0 } ) {
}
Here the baz
param does required a closure with 1 param of type String
and a return value of type Int
.
As you can see I added a default value to the param, a closure that does return 0
. Please note that the default closure will never be used so you can replace 0
with any Int
value you want.
Now you can decide whether to use pass your closure to the baz
param
class Boo {
let world = "world"
func boo() {
foo("hello") { (something) -> Int in
print(world)
return 100
}
}
}
Or, again, you can totally omit the baz
param.
class Boo {
let world = "world"
func boo() {
foo("hello")
}
}