如何快速进行可选的关闭?


93

我试图在Swift中声明一个需要可选闭包的参数。我声明的函数如下所示:

class Promise {

 func then(onFulfilled: ()->(), onReject: ()->()?){       
    if let callableRjector = onReject {
      // do stuff! 
    }
 }

}

但是Swift抱怨说,“ if let”声明时,“条件中的绑定值必须是Optional类型”。


考虑只使用一个带参数的闭包。
catanore '19

Answers:


113

您应该将可选的闭包括在括号中。这将适当地限制?操作员的范围。

func then(onFulfilled: ()->(), onReject: (()->())?){       
    if let callableRjector = onReject {
      // do stuff! 
    }
 }

您是否知道将其括在括号中的理由是什么?
Marcosc

5
可能消除歧义。如果可选的闭包具有返回值,那么它的()->Int?含义可能会引起混淆。
Cezar 2014年

3
另外,从Swift的书中:“在声明可选类型时,请确保使用括号正确地限定了?的范围。操作员。例如,要声明一个可选的整数数组,请将类型注释写为(Int [])?;。写Int []?产生错误。”
Cezar 2014年

@Cezar您能否解释一下为什么以及在何处使用“可选闭包”,我很好奇这一点。
iLearner

@Cezar目前不在Mac上,因此我的语法可能会略有不同,但请记住,?它实际上只不过是糖Optional<T>,因此您还可以编写`func then(onFulfilled:()->(),onReject:Optional <() ->()>){` (),尽管IMO ()?更漂亮,但您不需要额外的东西。您也可以使用像这样的类型别名使它更漂亮 typealias RejectHandler = () -> () func then(onFulfilled: ()->(), onReject: RejectHandler?) {
Andrew Carter,

62

为了使代码更短,我们可以在调用它时将其nil用作onReject参数的默认值和可选链接?()

func then(onFulfilled: ()->(), onReject: (()->())? = nil) {
  onReject?()
}

这样,我们可以onReject在调用then函数时省略参数。

then({ /* on fulfilled */ })

我们还可以使用结尾闭包语法将onReject参数传递给then函数:

then({ /* on fulfilled */ }) {
  // ... on reject
}

这是关于它的博客文章


34

既然我认为这个“可选”的闭包应该什么都不做,那么您可以使用一个带有空闭包的参数作为默认值:

func then(onFulfilled: ()->(), onReject: ()->() = {}){       
    // now you can call your closures
    onFulfilled()
    onReject()
}

现在可以在有或没有onReject回调的情况下调用此函数

then({ ... })
then({ ... }, onReject: { ... })

不需要Swift的超赞Optionals?


这是很好的解决方案!
罗兰T.17年

6

也许这是一种更清洁的方式。特别是当闭包具有复杂的参数时。

typealias SimpleCallBack = () -> ()

class Promise {

func then(onFulfilled: SimpleCallBack, onReject: SimpleCallBack?){       
    if let callableRjector = onReject {
        // do stuff! 
    }
}

}
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.