假设我们有一个像typealias
这样的协议:
// 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>
}
我想指定类似于let
/ var
声明的函数类型,并在其后加上可分配的类型:
/* -- 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)
???
我该如何实现?
可能的解决方法是将其转换为属性声明,但这很令人困惑:
var explicitAction: Action = { get }
答案 0 :(得分:4)
由于Action
是typealias
而不是类型,因此swift无法区分它们。
如documentation中所述:
声明类型别名后,可以在程序中的任何地方使用别名代替现有类型。现有类型可以是命名类型或复合类型。类型别名不会创建新类型。他们只是允许名称引用现有类型。
编辑:不好意思,我认为您想区分() -> Void
和Action
。
据我所知,使用闭包是快速完成此操作的唯一方法。
typealias Foo = (Int) -> Void
protocol FooBar {
var foo: Foo { get }
}
class FooBarBaz: FooBar {
var foo: Foo = { intValue in
// ...
}
}
编辑2:其他信息:
根据Grammar of a function declaration,声明功能的唯一方法是显式提供parameter-clause
,这需要在括号之间列出所有参数:
函数声明→函数头函数名称泛型子句 opt 函数签名泛型子句 opt 函数-body opt
功能签名→参数子句抛出 opt function-result opt
参数子句→()| (参数列表)
因此,显然,如果不使用闭包,就无法将类型声明为签名的函数。