再次回到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,就像之前那样。我们可以像之前所采用的两种方式那样调用它。