如何在Swift中“生成”闭包类型别名?
为了使我的代码更容易阅读,我在Swift中使用类型别名用于各种类型的闭包。 我有以下基本的闭包:
public typealias FailureClosure = (error: NSError?) -> Void public typealias ProgressClosure = (progress: Float32) -> Void public typealias BasicClosure = () -> Void
我想添加一个支持generics数组的闭包typealias
,但我似乎无法弄清楚它的语法。 这是我能够得到的,但我得到编译时错误“ 使用未声明的类型’T’ ”
public typealias ArrayClosure = (array:[T]?) -> Void
有人知道怎么做这个吗? 或者即使有可能吗?
不,这目前不可行。 如果可能的话,你期望的语法是:
public typealias ArrayClosure = (array:[T]?) -> Void
然后你会像ArrayClosure
一样使用它。 但它目前不合法。
也就是说,我不推荐这些类型的别名。 它们比它们照亮的模糊不清。 比较这个签名:
func foo(onError: FailureClosure)
有:
func foo(onError: NSError? -> Void)
要保存几个字符,可以强制调用者猜出FailureClosure
传递的内容。 error
或progress
标记对您没有实际帮助(您仍然需要progress in ...
使用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 }) }
我只是觉得理解发生的事情要容易一些。 但无论哪种方式都没问题。
编辑(2014年12月):在写了几个月的Swift之后,我在下面的评论中更加喜欢@David的方法,即使用一个可选的闭包,但不是错误。 特别是在Swift的可选链接语法( failure?()
)的情况下,它通常会更清晰。
func foo(failure: (NSError -> Void)? = nil)
Swift 4.1支持generics类别别名。 您可以使用此function为具有通用参数的函数提供名称。
您可能必须使用此类声明:
public typealias ArrayClosure = ([T]?) -> Void
- 在iOS Safari中debugging添加到主屏幕的Web应用程序
- ios:通过点击通知中心的消息启动检测应用程序
- iOS 10,Swift 3和Xcode 8即将面世-您准备好了吗?
- iPhone Objective-c检测屏幕锁定
- sorting在nsdictionary上给出不同的结果比在nsarraysorting
- 核心数据,当NSFetchRequest返回NSDictionaryResultType时如何获取NSManagedObject的ObjectId?
- UIView带来SubviewToFront:确实*不*将视图带到前面
- 在iOS中使用自定义字体的阿拉伯文字
- 为什么NSFileSystemFreeSize的值与iOS设置中报告的空闲大小不同?