gpt4 book ai didi

ios - 如何 "generify"Swift 中的闭包类型别名?

转载 作者:IT王子 更新时间:2023-10-29 05:19:26 25 4
gpt4 key购买 nike

为了使我的代码更易于阅读,我在 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

有人知道怎么做吗?或者即使有可能?

最佳答案

不,目前这是不可能的。如果它可能的,您期望的语法将是:

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

然后你会像ArrayClosure<Int>那样使用它.但它目前不合法。

也就是说,我真的不推荐这些类型别名。他们掩盖的多于他们阐明的。比较这个签名:

func foo(onError: FailureClosure)

与:

func foo(onError: NSError? -> Void)

为了只保存几个字符,你强制调用者猜测是什么 FailureClosure通过。 errorprogress标签并不能真正帮助你(你仍然需要使用 progress in ... )。

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

public typealias Progress = Float32

不要误会我的意思,类型别名在创建新类型 时非常有用。 Progress是一种恰好实现为 float 的类型。但是您正在做的大部分事情(肯定是使用 ArrayClosure ,并且在较小程度上使用其他方法)只是创建新语法而不创建新类型,这往往令人困惑而不是有用。


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

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

你是对的,这真的很复杂。比较:

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

这里有两个大的变化。没有理由有一个带有可选错误的失败 block 。始终传递错误(如果没有错误,为什么会调用 failure?)。没有理由让失败 block 成为可选的。如果你真的想要一个默认值,就让默认值什么也不做。两个可选项消失了,所有的消费和实现代码都变得更简单了。始终仔细考虑某些东西是否绝对必须是可选的。可选项增加了很多复杂性;不要轻易添加它们。

就我个人而言,在很多情况下我可能会使用重载来代替:

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

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

我只是认为它更容易理解正在发生的事情。但无论哪种方式都可以。


编辑(2014 年 12 月):在编写 Swift 几个月后,我越来越喜欢@David 在下面评论中的方法,即使用可选的闭包,而不是错误。特别是考虑到 Swift 的可选链接语法 ( failure?() ),它通常会变得更加清晰。

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

关于ios - 如何 "generify"Swift 中的闭包类型别名?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25909856/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com