函数式 Swift--1.函数式编程
2017-08-14 本文已影响40人
达摩君
1.观看 函数式Swift笔记
避免使用程序状态和可变对象,是降低程序复杂度的有效方式之一,而这也正是函数式编程的精髓。函数式编程强调执行的结果,而非执行的过程。我们先构建一系列简单却具有一定功能的小函数,然后再将这些函数进行组装以实现完整的逻辑和复杂的运算,这是函数式编程的基本思想。
柯里化
一般当我们有二个参数的时候,我们定义的方法基本都是:
func add1(_ x: Int, _ y: Int) -> Int {
return x + y
}
然而在 Swift 中,我们对该函数的定义还可以有另一个版本
func add2(_ x: Int) -> ((Int) -> Int) {
return { y in x + y }
}
这里的 add2 函数接受第一个参数 x 之后,返回一个闭包,然后再接受第二个参数 y。这与滤镜函数的结构一模一样。
因为该函数的箭头向右结合 (right-associative),所以我们可以移除包围在结果函数类型周围的括号。从而得到本质上与 add2 完全等价的函数 add3:
func add3(_ x: Int) -> (Int) -> Int {
return { y in x + y }
}
结果都是一样的
let a = add1(1, 2)
let b = add3(1)(2)
print(a,b) // 3,3
记得以前看喵神的swift,第一篇好像就是讲柯里化,雨里雾里的,现在回过头看看貌似懂了一点哈~
封装 Core Image
由于书上没有demo下载,自己敲了一边,demo在此!
import Foundation
import UIKit
import CoreImage
//将 Filter 类型定义为一个函数,该函数接受一个图像作为参数并返回一个新的图像
typealias Filter = (CIImage) -> (CIImage)
///高斯模糊
func blur(radius: Double) -> Filter {
return { image in
let paraeters: [String: Any] = [
kCIInputRadiusKey: radius,
kCIInputImageKey: image
]
guard let filter = CIFilter(name: "CIGaussianBlur", withInputParameters: paraeters) else {
fatalError()
}
guard let outputImage = filter.outputImage else {
fatalError()
}
return outputImage
}
}
///生成固定颜色的滤镜
func generate(color: UIColor) -> Filter {
return { _ in
let parameters = [kCIInputColorKey: CIColor(cgColor: color.cgColor)]
guard let filter = CIFilter(name: "CIConstantColorGenerator", withInputParameters: parameters) else {
fatalError()
}
guard let outputImage = filter.outputImage else {
fatalError()
}
return outputImage
}
}
///定义合成滤镜
func compositeSourceOver(overlay: CIImage) -> Filter {
return { image in
let parameters = [
kCIInputBackgroundImageKey: image,
kCIInputImageKey: overlay
]
guard let filter = CIFilter(name: "CISourceOverCompositing",
withInputParameters: parameters)
else { fatalError() }
guard let outputImage = filter.outputImage
else { fatalError() }
return outputImage.cropping(to: image.extent)
}
}
///结合两个滤镜来创建颜色叠层滤镜
func overlay(color: UIColor) -> Filter {
return { image in
let overlay = generate(color: color)(image).cropping(to: image.extent)
return compositeSourceOver(overlay: overlay)(image)
}
}
func compose(filter filter1: @escaping Filter, with filter2: @escaping Filter) -> Filter {
return {
image in filter2(filter1(image))
}
}
///中间运算符 自定义运算符 运算符 >>> 默认是左结合的 (left-associative)
infix operator >>>
func >>>(filter1: @escaping Filter, filter2: @escaping Filter) -> Filter {
return {
image in filter2(filter1(image))
}
}
在控制器中展示:
let url = URL(string: "https://www.objc.io/images/covers/16.jpg")!
let color = UIColor.red.withAlphaComponent(0.2)
let image = CIImage(contentsOf: url)!
let blurredImage = blur(radius: 5.0)(image)
let overlaidImage = overlay(color: color)(blurredImage) // 1.
let composeImage = compose(filter: blur(radius: 5.0), with: overlay(color: color))
let result1 = composeImage(image) // 2/
let blurOver = blur(radius: 5.0)>>>overlay(color: color) // 3.
img.image = UIImage(ciImage: blurOver(image))
跟着敲一遍,感受一下函数式编程的魅力,慢慢学习中~
效果如下:
