我如何“生成” Swift中的闭包类型别名? [英] How do I "generify" a closure type alias in Swift?

查看:136
本文介绍了我如何“生成” Swift中的闭包类型别名?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

为了使我的代码更容易阅读,我在Swift中为各种类型的闭包使用类型别名。我有以下基本的闭包集:

In order to make my code easier to read, I am using type aliases in Swift for various types of closures. I have the following basic set of closures:

public typealias FailureClosure = (error: NSError?) -> Void
public typealias ProgressClosure = (progress: Float32) -> Void
public typealias BasicClosure = () -> Void

我想添加一个闭包 typealias 支持通用数组,但我似乎无法找出它的语法。这是我能够得到,但我得到编译时错误 使用未声明的类型'T'

I would like to add a closure typealias that supports generic arrays, but I can't seem to figure out the syntax for it. This is as far as I am able to get, but I get the compile time error "Use of undeclared type 'T'"

public typealias ArrayClosure = <T>(array:[T]?) -> Void

有人知道如何做吗?

不,这是目前不可能的。

解决方案

如果可能,您期望的语法将是:

No, this is not currently possible. If it were possible, the syntax you'd expect would be:

public typealias ArrayClosure<T> = (array:[T]?) -> Void

然后使用 ArrayClosure< Int> 。但它目前不合法。

You would then use it like ArrayClosure<Int>. But it's not currently legal.

也就是说,我真的不推荐这些类型别名。他们掩盖比他们照亮更多。比较此签名:

That said, I don't really recommend these type aliases. They obscure more than they illuminate. Compare this signature:

func foo(onError: FailureClosure)

与:

func foo(onError: NSError? -> Void)

要保存几个字符,强制调用者猜测 FailureClosure 通过。 错误进度标签不能真正帮助你(你仍然需要使用进度in ... )。

To save just a couple of characters, you force the caller to guess what FailureClosure passes. The error or progress tags don't really help you (you still need to use progress in ...).

一个很有意义的例子是 progress ,但我想你想要的类型是:

The one case that makes a lot of sense is around progress, but I think the type you want there is:

public typealias Progress = Float32

在这里不要误解,类型别名在创建新的类型时会非常有用。 进度是一种类型,恰好实现为float。但是你所做的大部分工作(绝对使用 ArrayClosure ,而在其他方面)只是创建新的语法,而不创建一个新的类型,这是更多经常混淆而不是有帮助。

Don't get me wrong here, type aliasing can be very helpful when it creates a new type. Progress is a type that happens to be implemented as as float. But much of what you're doing (definitely with ArrayClosure, and to a lesser extent with the others) is just creating new syntax without creating a new type, and that is more often confusing than helpful.

要说明您的具体示例,以及为什么过度使用类型别名会导致设计过度复杂:

To call out your specific example, and why overuse of type aliases can cause you to overcomplicate your design:

func foo(failure: ((error: NSError?) -> ())? = nil)

这是真的很复杂。比较:

You're right that this is really complicated. Compare:

func foo(failure: NSError -> Void = {_ in return})

这里有两个很大的变化。没有理由让失败块发生可选错误。始终传递错误(如果没有错误,为什么失败被调用?)。并且没有理由使故障块是可选的。如果你真的想要一个默认值,只是使默认值什么也不做。两个可选项消失了,所有的消费和实现代码变得更简单。总是仔细考虑是否绝对必须是可选的。可选添加了很多复杂性;

Two big changes here. There's no reason to have a failure block that takes an optional error. Always pass an error (if there's no error, why would failure be called?). And there's no reason for the failure block to be optional. If you really want a default value, just make the default value do nothing. Two optionals gone, and all the consuming and implementing code gets simpler. Always think carefully about whether something absolutely must be optional. Optionals add a lot of complexity; don't add them lightly.

个人而言,在很多情况下,我可能会用超载代替这种情况:

Personally, I'd probably do this with an overload instead in many cases:

func foo(#failure: NSError -> Void) { ...  }

func foo() {
  foo(failure:{ _ in return })
}

我只是想更容易理解继续。但是任何一种方式都很好。

I just think it's a little easier to understand what's going on. But either way is fine.

编辑(2014年12月):在写Swift几个月后,在下面的评论中更喜欢@ David的方法,这是使用一个可选的闭包,但不是为错误。特别是给了Swift的可选链接语法( failure?()),它往往会变得更清楚。

EDIT (Dec 2014): After writing Swift for a few more months, I've grown more fond of @David's approach in the comments below, which is to use an optional for the closure, but not for the error. Particularly given Swift's optional chaining syntax (failure?()), it often does wind up being clearer.

func foo(failure: (NSError -> Void)? = nil)

这篇关于我如何“生成” Swift中的闭包类型别名?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆