Reputation: 3058
Suppose, we have a protocol with typealias
es like this:
// common closure types
typealias Action = () -> Void
typealias Consumer<T> = (T) -> Void
// here starts the fun
typealias AsyncAction = (Action?) -> Void
typealias AsyncGetter<T> = (Consumer<T>?) -> Void
typealias AsyncSetter<T> = (T, Action?) -> Void
// make compiler and you happy
typealias Foo = Void
typealias Bar = Void
protocol FooBarDatabaseAccess {
func doSomething()
func doSomethingAsync(completion: Action?)//: AsyncAction
func getFooAsync(completion: Consumer<Foo>?)//: AsyncGetter<Foo>
func getBarAsync(completion: Consumer<Bar>?)//: AsyncGetter<Bar>
func setBarAsync(value: Bar, completion: Action?)//: AsyncSetter<Bar>
}
I would like to specify the function type similar to let
/var
declarations with a colon followed by its assignable type:
/* -- let/var -- */
// implicitly typed as String, determined from initial assignment
let implicitString = ""
// explicitly typed as String, though initialisation is omitted here
let explicitString: String
/* -- func -- */
// implicitly typed as () -> Void, determined from argument/return type(s)
func implicitAction()
// explicitly typed as Action, compiler should complain if it does not conform to the type (alias)
???
How can I achieve that?
A possible workaround is to transform it into a property declaration, but that is confusing:
var explicitAction: Action = { get }
Upvotes: 0
Views: 257
Reputation: 11066
As Action
is a typealias
and not a type, swift can't differentiate them.
As explained in the documentation:
After a type alias is declared, the aliased name can be used instead of the existing type everywhere in your program. The existing type can be a named type or a compound type. Type aliases do not create new types; they simply allow a name to refer to an existing type.
Edit: My bad, I thought you wanted to differentiate () -> Void
and Action
.
As far as I know, using a closure is the only way of doing this in swift.
typealias Foo = (Int) -> Void
protocol FooBar {
var foo: Foo { get }
}
class FooBarBaz: FooBar {
var foo: Foo = { intValue in
// ...
}
}
Edit 2: Additional information:
According to the Grammar of a function declaration, the only way of declaring a function is to explicitly provide a parameter-clause
, which require listing all parameters between parentheses:
function-declaration → function-head function-name generic-parameter-clauseopt function-signature generic-where-clauseopt function-bodyopt
function-signature → parameter-clause throwsopt function-resultopt
parameter-clause → ( ) | ( parameter-list )
So apparently, it's not possible to declare a function with a type as signature without using a closure.
Upvotes: 4