我的目标是使用 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
”作为其类型注释。
最佳答案
闭包是未命名的闭包表达式,这就是为什么我们可以使用函数类型typealias
来指定闭包的类型,即使对于具有非空的闭包也是如此参数列表。
typealias VoidToVoid = () -> ()
typealias IntToVoid = (Int) -> ()
// unnamed closure expressions
let f: VoidToVoid = { print("foo") }
let g: IntToVoid = { print($0) }
请注意,这些示例中的 f
和 g
不是函数:它们只是保存对(后备存储)的引用的不可变属性的)声明时指定的未命名闭包。
另一方面,函数是闭包的特例;一个有名字的闭包。此外,任何具有非空参数列表的函数都需要在其声明中提供内部(和可选)和外部参数名称。但是,函数类型 typealias
可能不包含其参数名称的参数标签:
typealias IntToVoid = (a: Int) -> ()
/* Error: function types cannot have argument
label 'a'; use '_' instead */
这意味着函数类型 typealias
不能用于替代函数的组合参数和返回类型声明部分(即使在 () -> ( )
大小写).
详情见例:
Closures
...
Global and nested functions, as introduced in Functions, are actually special cases of closures. Closures take one of three forms:
- Global functions are closures that have a name and do not capture any values.
- Nested functions are closures that have a name and can capture values from their enclosing function.
- Closure expressions are unnamed closures written in a lightweight syntax that can capture values from their surrounding context.
另一方面,您可以自然地测试给定函数的类型是否为某些现有函数类型 typealias
。
typealias VoidToVoid = () -> ()
typealias IntToVoid = (Int) -> ()
func f() -> () {}
func g(_ a: Int) -> () { _ = a }
print(f is VoidToVoid) // true
print(g is IntToVoid) // true
关于swift - 用类型别名注释整个函数声明,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41952897/