为了使我的代码更容易阅读,我在Swift中使用类型别名来处理各种类型的闭包。我有以下基本闭包:
public typealias FailureClosure = (error: NSError?) -> Void
public typealias ProgressClosure = (progress: Float32) -> Void
public typealias BasicClosure = () -> Void
我想添加一个支持泛型数组的闭包typealias
,但我似乎无法弄清楚它的语法。这是我能够得到的,但我得到编译时错误“ 使用未声明类型'T' ”
public typealias ArrayClosure = <T>(array:[T]?) -> Void
有人知道怎么做吗?或者即使有可能吗?
答案 0 :(得分:11)
不,目前无法实现。如果 可能,那么您期望的语法是:
public typealias ArrayClosure<T> = (array:[T]?) -> Void
然后你会像ArrayClosure<Int>
一样使用它。但它目前不合法。
那就是说,我不是真的推荐这些类型的别名。它们模糊不清,而不是照亮它们。比较这个签名:
func foo(onError: FailureClosure)
使用:
func foo(onError: NSError? -> Void)
要保存几个字符,您可以强制调用者猜出FailureClosure
通过的内容。 error
或progress
标记对您没有帮助(您仍然需要使用progress in ...
)。
一个很有意义的案例是progress
,但我认为你想要的类型是:
public typealias Progress = Float32
这里不要误解我,在创建新的类型时输入别名会非常有用。 Progress
是一种碰巧实现为float的类型。但是你正在做的很多事情(肯定与ArrayClosure
有关,而在较小程度上与其他人一样)只是在不创建新类型的情况下创建新语法,而这通常会让人感到困惑而不是有用。
调出您的具体示例,以及为什么过度使用类型别名会导致您的设计过于复杂:
func foo(failure: ((error: NSError?) -> ())? = nil)
你说得对,这真的很复杂。比较:
func foo(failure: NSError -> Void = {_ in return})
这里有两大变化。没有理由有一个带有可选错误的故障块。始终传递错误(如果没有错误,为什么会调用failure
?)。并且没有理由将故障块作为可选项。如果您确实需要默认值,只需使默认值不执行任何操作。两个选项消失了,所有消费和实现代码变得更简单。始终要仔细考虑是否绝对必须是可选的。可选项增加了很多复杂性;不要轻易添加它们。
就个人而言,在很多情况下,我可能会以过载的方式做到这一点:
func foo(#failure: NSError -> Void) { ... }
func foo() {
foo(failure:{ _ in return })
}
我认为它更容易理解发生了什么。但无论哪种方式都没问题。
failure?()
),它经常会更清晰。
func foo(failure: (NSError -> Void)? = nil)
答案 1 :(得分:0)
Swift 4.1支持通用类型别名。您可以使用此功能为具有通用参数的函数提供名称。
您可能必须使用以下声明:
public typealias ArrayClosure<T> = ([T]?) -> Void