Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Swift: reusing a closure definition (with typealias)

I'm trying to do create some closure definitions which I'm gonna use a lot in my iOS app. So I thought to use a typealias as it seemed the most promising ...

I did a small Playground example which shows my issue in detail

// Here are two tries for the Closure I need
typealias AnonymousCheck = (Int) -> Bool
typealias NamedCheck = (number: Int) -> Bool

// This works fine
var var1: AnonymousCheck = {
    return $0 > 0
}
var1(-2)
var1(3343)

// This works fine
var var2: NamedCheck = {
    return $0 > 0
}
var2(number: -2)
var2(number: 12)

// But I want to use the typealias mainly as function parameter!
// So:

// Use typealias as function parameter
func NamedFunction(closure: NamedCheck) {
    closure(number: 3)
}
func AnonymousFunction(closure: AnonymousCheck) {
    closure(3)
}

// This works as well
// But why write again the typealias declaration?
AnonymousFunction({(another: Int) -> Bool in return another < 0})
NamedFunction({(another: Int) -> Bool in return another < 0})

// This is what I want... which doesn't work
// ERROR: Use of unresolved identifier 'number'
NamedFunction({NamedCheck in return number < 0})

// Not even these work
// ERROR for both: Anonymous closure arguments cannot be used inside a closure that has exlicit arguments
NamedFunction({NamedCheck in return $0 < 0})
AnonymousFunction({AnonymousCheck in return $0 < 0})

Am I missing something or is it just not supported in Swift? Thanks

EDIT/ADDITION:

The above is just a simple example. In real life my typealias is more complicated. Something like:

typealias RealLifeClosure = (number: Int, factor: NSDecimalNumber!, key: String, upperCase: Bool) -> NSAttributedString

I basically want to use a typealias as a shortcut so I don't have to type that much. Maybe typealias isn't the right choice... Is there another?

like image 960
Soko Avatar asked Jan 06 '15 17:01

Soko


People also ask

How do I use Typealias in Swift?

A type alias allows you to provide a new name for an existing data type into your program. After a type alias is declared, the aliased name can be used instead of the existing type throughout the program. Type alias do not create new types. They simply provide a new name to an existing type.

Can a closure be assigned to a variable Swift?

Closures are self-contained blocks of functionality that can be passed around and used in your code. Said differently, a closure is a block of code that you can assign to a variable. You can then pass it around in your code, for instance to another function.

How do you pass closure in Swift?

If we wanted to pass that closure into a function so it can be run inside that function, we would specify the parameter type as () -> Void . That means “accepts no parameters, and returns Void ” – Swift's way of saying “nothing”.

How many types of closures are there in Swift?

As shown in the above table, there are three types of closures in Swift, namely global functions, nested functions, and closure expressions. They differ in several aspects, including their use scopes, their names, and whether they capture values, which will be discussed more in a later section.


1 Answers

You aren't rewriting the typealias declaration in this code, you're declaring the parameters and return type:

AnonymousFunction({(another: Int) -> Bool in return another < 0})

Happily, Swift's type inference lets you use any of the following - pick the style that feels best to you:

AnonymousFunction( { (number: Int) -> Bool in number < 0 } )
AnonymousFunction { (number: Int) -> Bool in number < 0 }
AnonymousFunction { (number) -> Bool in number < 0 }
AnonymousFunction { number -> Bool in number < 0 }
AnonymousFunction { number in number < 0 }
AnonymousFunction { $0 < 0 }
like image 152
Nate Cook Avatar answered Oct 14 '22 23:10

Nate Cook