首页 » iOS编程基础:Swift、Xcode和Cocoa入门指南 » iOS编程基础:Swift、Xcode和Cocoa入门指南全文在线阅读

《iOS编程基础:Swift、Xcode和Cocoa入门指南》2.14 柯里化函数

关灯直达底部

再次回到makeRoundedRectangleMaker:


func makeRoundedRectangleMaker(sz:CGSize) ->  -> UIImage {    return {        imageOfSize(sz) {            let p = UIBezierPath(                roundedRect: CGRect(origin:CGPointZero, size:sz),                cornerRadius: 8)            p.stroke        }    }}  

我对上述方法的一个地方不太满意:它所创建的圆角矩形的尺寸是个参数(sz),不过圆角矩形的cornerRadius却是硬编码的8,我希望能够为圆角半径指定值。有两种方式可以做到这一点。一种是为makeRoundedRectangleMaker本身再提供一个参数:


func makeRoundedRectangleMaker(sz:CGSize, _ r:CGFloat) ->  -> UIImage {    return {        imageOfSize(sz) {            let p = UIBezierPath(                roundedRect: CGRect(origin:CGPointZero, size:sz),                cornerRadius: r)            p.stroke        }    }}  

然后像下面这样调用:


let maker = makeRoundedRectangleMaker(CGSizeMake(45,20), 8)  

还有另外一种方式。现在,makeRoundedRectangleMaker所返回的函数不接收参数,我们可以让它接收一个参数:


func makeRoundedRectangleMaker(sz:CGSize) -> (CGFloat) -> UIImage {    return {        r in        imageOfSize(sz) {            let p = UIBezierPath(                roundedRect: CGRect(origin:CGPointZero, size:sz),                cornerRadius: r)            p.stroke        }    }}  

现在,makeRoundedRectangleMaker所返回的函数会接收一个参数,因此在调用时需要将这个参数提供给它:


let maker = makeRoundedRectangleMaker(CGSizeMake(45,20))self.myImageView.image = maker(8)  

如果不需要保存maker供其他地方使用,那就可以在一行完成所有这些事情:函数调用会生成一个函数,我们再立刻调用该函数来获取图片:


self.myImageView.image = makeRoundedRectangleMaker(CGSizeMake(45,20))(8)  

如果函数返回的函数接收一个参数,就像该示例这样,那么它就叫作柯里化函数(为了纪念计算机科学家Haskell Curry)。Swift提供了柯里化函数的便捷声明方式;可以省略第1个箭头运算符与顶层匿名函数,如以下代码所示:


func makeRoundedRectangleMaker(sz:CGSize)(_ r:CGFloat) -> UIImage {   return imageOfSize(sz) {       let p = UIBezierPath(           roundedRect: CGRect(origin:CGPointZero, size:sz),           cornerRadius: r)       p.stroke   }}  

表达式(sz:CGSize)(_r:CGFloat)(一行有两个参数列表,并且中间没有箭头运算符)表示“Swift,请对该函数进行柯里化”。Swift会将函数划分到两个函数中,一个是makeRoundedRectangleMaker,接收CGSize参数,另一个是匿名函数,接收CGFloat。代码看起来好像是makeRoundedRectangleMaker会返回一个UIImage,不过实际上它返回的是一个函数,该函数会返回一个UIImage,就像之前那样。我们可以像之前所采用的两种方式那样调用它。