使用typealias注释整个函数声明

时间:2017-01-31 08:30:44

标签: swift function types

我的目标是使用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"作为其类型注释。

1 个答案:

答案 0 :(得分:3)

闭包是未命名的闭包表达式,这就是为什么我们可以使用函数类型typealias来指定闭包的类型,即使对于具有非空参数列表的闭包也是如此。

typealias VoidToVoid = () -> ()
typealias IntToVoid = (Int) -> ()

                  // unnamed closure expressions
let f: VoidToVoid = { print("foo") }
let g: IntToVoid  = { print($0) }

请注意,这些exaples中的fg 不是函数:它们只是不可变属性,它们保存对指定的未命名闭包(的后备存储)的引用在宣布时。

另一方面,一个函数是一个闭包的特例;一个带名字的封口。此外,具有非空参数列表的任何函数都需要在其声明中提供内部(以及可选)和外部参数名称​​。但是,函数类型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