我的目标是使用typealias
作为单词提醒“附加”到函数声明中。说,
typealias VoidToVoid = () -> ()
我可以在陈述闭包的预期类型时使用类型别名,因此
let f : VoidToVoid = { return }
assert(f is VoidToVoid)
但是,这似乎不是声明函数的最常用方法。我希望有一种方法告诉读者,下面的f′
声明的函数应该是VoidToVoid
类型,并使用该名称。
(但没有读者必须推断,或思考,或等待编译器告诉他或她关于类型。加剧情况,编译器无法知道类型别名我想用f′
并且可能会输出说明裸类型的消息,而不是别名。)
func f′() : VoidToVoid { // tentative syntax
return
}
我可以到那儿去吗?
编辑:要使用类型别名,有两个目的地。一方面,现在可以:
func giveMeAClosure(_ f: VoidToVoid) {
f()
}
另一方面,VoidToVoid
是隐含的:
func canBeGivenAsClosure() {
// ...
}
也就是说,在声明canBeGivenAsClosure
的情况下,通过VoidToVoid
在两端之间存在连接是正确但不明显的。这与let
案例不同,后者可以包含" VoidToVoid
"作为其类型注释。
答案 0 :(得分:3)
闭包是未命名的闭包表达式,这就是为什么我们可以使用函数类型typealias
来指定闭包的类型,即使对于具有非空参数列表的闭包也是如此。
typealias VoidToVoid = () -> ()
typealias IntToVoid = (Int) -> ()
// unnamed closure expressions
let f: VoidToVoid = { print("foo") }
let g: IntToVoid = { print($0) }
请注意,这些exaples中的f
和g
不是函数:它们只是不可变属性,它们保存对指定的未命名闭包(的后备存储)的引用在宣布时。
另一方面,一个函数是一个闭包的特例;一个带名字的封口。此外,具有非空参数列表的任何函数都需要在其声明中提供内部(以及可选)和外部参数名称。但是,函数类型typealias
可能不包含其参数名称的参数标签:
typealias IntToVoid = (a: Int) -> ()
/* Error: function types cannot have argument
label 'a'; use '_' instead */
这意味着函数类型typealias
不能用于替代函数的组合参数和返回类型声明部分(即使在() -> ()
情况下也是如此)。 / p>
有关详情,请参阅例如:
<强>闭包强>
...
实际上是Functions中介绍的全局和嵌套函数 特殊情况的封闭。闭包采用以下三种形式之一:
- 全局函数是具有名称且不捕获任何值的闭包。
- 嵌套函数是具有名称的闭包,可以从其封闭函数中捕获值。
- Closure表达式是一种未命名的闭包,用轻量级语法编写,可以从周围的上下文中捕获值。
另一方面,您可以自然地测试给定函数的类型到某个现有函数类型typealias
。
typealias VoidToVoid = () -> ()
typealias IntToVoid = (Int) -> ()
func f() -> () {}
func g(_ a: Int) -> () { _ = a }
print(f is VoidToVoid) // true
print(g is IntToVoid) // true