美文网首页
函数式 Swift--1.函数式编程

函数式 Swift--1.函数式编程

作者: 达摩君 | 来源:发表于2017-08-14 21:33 被阅读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))

跟着敲一遍,感受一下函数式编程的魅力,慢慢学习中~
效果如下:

高斯模糊加滤镜.png

相关文章

网友评论

      本文标题:函数式 Swift--1.函数式编程

      本文链接:https://www.haomeiwen.com/subject/nfayrxtx.html