美文网首页
函数式Swift的些许知识点

函数式Swift的些许知识点

作者: rxdxxxx | 来源:发表于2017-12-05 14:23 被阅读19次

函数式Swift的知识点

@escaping 逃逸闭包

“当需要在函数返回之后使用其参数(如:region)时,该参数需要被标记为 @escaping。即使忘记标记,编译器也将会提醒我们。如果你想了解更详细的信息,请参阅 Apple 的 The Swift Programming Language 一书中《逃逸闭包》的部分。”

柯里化

形如 blur(radius: radius)(image)

参数的分别传入计算函数的, 这样的形式更易于函数的组合.

Map函数的实现

extension Array {
    func map<T>(_ transform: (Element) -> T) -> [T] {
        var result: [T] = []
        for x in self {
            result.append(transform(x))
        }
        return result
    }
}

  • 使用
func genericCompute<T>(array: [Int], transform: (Int) -> T) -> [T] {
    return array.map(transform)
}

Filter函数的实现

extension Array {
    func filter(_ includeElement: (Element) -> Bool) -> [Element] {
        var result: [Element] = []
        for x in self where includeElement(x) {
            result.append(x)
        }
        return result
    }
}

  • 使用
func getSwiftFiles(in files: [String]) -> [String] {
    return files.filter { file in file.hasSuffix(".swift") }
}


Reduce函数实现

  • 一般的Reduce行为
func prettyPrint(strings: [String]) -> String {
    var result: String = "Entries in the array xs:\n"
    for string in strings {
        result = " " + result + string + "\n"
    }
    return result
}

  • 泛型实现

extension Array {
    func reduce<T>(_ initial: T, combine: (T, Element) -> T) -> T {
        var result = initial
        for x in self {
            result = combine(result, x)
        }
        return result
    }
}

  • 使用Reduce 实现 Map 和 Filter
extension Array {
    func mapUsingReduce<T>(_ transform: (Element) -> T) -> [T] {
        return reduce([]) { result, x in
            return result + [transform(x)]
        }
    }
    func filterUsingReduce(_ includeElement: (Element) -> Bool) -> [Element] {
        return reduce([]) { result, x in
            return includeElement(x) ? result + [x] : result
        }
    }
}

实际运用 Map Filter和Reduce

struct City {
    let name: String
    let population: Int
}

我们可以定义一些示例城市:

let paris = City(name: "Paris", population: 2241)
let madrid = City(name: "Madrid", population: 3165)
let amsterdam = City(name: "Amsterdam", population: 827)
let berlin = City(name: "Berlin", population: 3562)
let cities = [paris, madrid, amsterdam, berlin]

假设我们现在想筛选出居民数量至少一百万的城市,并打印一份这些城市的名字及总人口数的列表。我们可以定义一个辅助函数来换算居民数量:

extension City {
    func scalingPopulation() -> City {
        return City(name: name, population: population * 1000)
    }
}

现在我们可以使用所有本章中见到的函数来编写下面的语句:

cities.filter { $0.population > 1000 }
    .map { $0.scalingPopulation() }
    .reduce("City: Population") { result, c in
        return result + "\n" + "\(c.name): \(c.population)"
}
/*
 City: Population
 Paris: 2241000
 Madrid: 3165000
 Berlin: 3562000
 */
 

泛型和Any类型

泛型: 具备编辑器的类型检查, 使用泛型更具有通用性

Any: 则可以避开Swift的类型系统

可选值

let cities = ["Paris": 2241, "Madrid": 3165, "Amsterdam": 827, "Berlin": 3562]

可选绑定

if let madridPopulation = cities["Madrid"] {
    print("The population of Madrid is \(madridPopulation * 1000)")
} else {
    print("Unknown city: Madrid")
}


?? 运算符

默认值使用闭包, 可以避免不必要的计算

这里是运用的重点: 闭包的使用!!!

infix operator ??
func ??<T>(optional: T?, defaultValue: @autoclosure () throws -> T) rethrows -> T {
    if let x = optional {
        return x
    } else {
        return try defaultValue()
    }
}

if 可选链

if let myState = order.person?.address?.state {
    print("This order will be shipped to \(myState)")
} else {
    print("Unknown person, address, or state.")
}

switch 的可选值

可以再case中使用 ? 解绑可选值

switch madridPopulation {
case 0?: print("Nobody in Madrid")
case (1..<1000)?: print("Less than a million in Madrid")
case let x?: print("\(x) people in Madrid")
case nil: print("We don't know about Madrid")
}

guard 的可选值

func populationDescription(for city: String) -> String? {
    guard let population = cities[city] else { return nil }
    return "The population of Madrid is \(population)"
}


可选映射 Optional.map

Optional 也提供了 map 函数, 可以对其解绑值进行处理

extension Optional {
    func map<U>(_ transform: (Wrapped) -> U) -> U? {
        guard let x = self else { return nil }
        return transform(x)
    }
}

func increment(optional: Int?) -> Int? {
    return optional.map { $0 + 1 }
}

flatMap帮助解绑

其区别是和 map 的参数闭包的返回值类型 仍然是 可选类型

extension Optional {
    func flatMap<U>(_ transform: (Wrapped) -> U?) -> U? {
        guard let x = self else { return nil }
        return transform(x)
    }
}


extension Array{    
    func myFlatMap<T>(_ transform: (Element) -> [T]) -> [T] {
        var tmp: [T] = []
        for value in self {
            tmp.append(contentsOf: transform(value));
        }
        return tmp; 
    }
}

相关文章

网友评论

      本文标题:函数式Swift的些许知识点

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