Swift 5.1 温故而知新笔记系列之第七天

1.函数式编程

函数式编程(Funtional Programming,简称FP)是一种编程范式,也就是如何编写程序的方法论

  • 主要思想:把计算过程尽量分解成一系列可复用函数的调用
  • 主要特征:函数是“第一等公民”
  • 函数与其他数据类型一样的地位,可以赋值给其他变量,也可以作为函数参数、函数返回值

示例一

传统写法

//[(num + 3) * 5 - 1] % 10 / 2
func add(_ v1: Int, _ v2: Int) -> Int{ v1 + v2 }
func sub(_ v1: Int, _ v2: Int) -> Int{ v1 - v2 }
func multiple(_ v1: Int, _ v2: Int) -> Int{ v1 * v2 }
func divide(_ v1: Int, _ v2: Int) -> Int{ v1 / v2 }
func mod(_ v1: Int, _ v2: Int) -> Int{ v1 % v2 }

var num: Int = 1

print(divide(mod(sub(multiple(add(num, 3), 5), 1), 10), 2))

函数式

// 中缀运算符
//infix operator >>> : AdditionPrecedence
//func >>> (_ v1: Int, _ v2: Int) -> Int{
//    return v1 + v2
//}
//
//var num1 = 20
//var num2 = 30
 50
//print(num1 >>> num2)

// [(num + 3) * 5 - 1] % 10 / 2
func add(_ v: Int) -> (Int) -> Int { {$0 + v} }
func sub(_ v: Int) -> (Int) -> Int { {$0 - v} }
func multiple(_ v: Int) -> (Int) -> Int { {$0 * v} }
func divide(_ v: Int) -> (Int) -> Int { {$0 / v} }
func mod(_ v: Int) -> (Int) -> Int { {$0 % v} }

infix operator >>> : AdditionPrecedence
func >>><A,B,C>(_ f1: @escaping (A) -> B,
         _ f2: @escaping (B) -> C) -> (A) -> C { { f2(f1($0)) } }


var fn = add(3) >>> multiple(5) >>> sub(1) >>> mod(10) >>> divide(2)
print(fn(1))

高阶函数

  • 接受一个或者多个函数作为输入(map,filter,reduce)
  • 作为返回值

柯里化

  • 将一个接受多参数的函数变换为一系列只接受单个参数的函数

手动柯里化

// 两个参数柯里化
func sub1(_ v1: Int, _ v2: Int) -> Int { v1 - v2 }

print(sub1(10,20))

func sub1(_ v1: Int) -> (Int) -> Int {
    return {
        v2 in
        return v1 - v2
    }
}

print(sub1(10)(20))


// 三个参数柯里化
func sub3(_ v1: Int, _ v2: Int, _ v3: Int) -> Int { v1 - v2 - v3 }
print(sub3(10, 20, 30))


func sub4(_ v1: Int) -> (Int) -> (Int) -> Int {
    return { v2 in
        return { v3 in
            return v1 - v2 - v3
        }
    }
}

print(sub4(10)(20)(30))

通用柯里化


func sub1(_ v1: Int, _ v2: Int) -> Int { v1 - v2 }

func sub2(_ v1: Int, _ v2: Int, _ v3: Int) -> Int { v1 - v2 - v3 }


prefix func ~<A, B, C>(_ fn: @escaping (A, B) -> C) -> (B) -> (A) -> C {
    { b in { a in fn(a, b) } }
}

prefix func -<A, B, C, D>(_ fn: @escaping (A, B, C) -> D) -> (C) -> (B) -> (A) -> D {
    { c in { b in { a in fn(a, b, c)} } }
}


print(sub1(20, 10))
print((~sub1)(10)(20))

print(sub2(10,20,30))
print((-sub2)(30)(20)(10))

// [(num + 3) * 5 - 1] % 10 / 2

func add(_ v1: Int, _ v2: Int) -> Int{ v1 + v2 }
func sub(_ v1: Int, _ v2: Int) -> Int{ v1 - v2 }
func multiple(_ v1: Int, _ v2: Int) -> Int{ v1 * v2 }
func divide(_ v1: Int, _ v2: Int) -> Int{ v1 / v2 }
func mod(_ v1: Int, _ v2: Int) -> Int{ v1 % v2 }

infix operator >>> : AdditionPrecedence
func >>><A,B,C>(_ f1: @escaping (A) -> B,
                _ f2: @escaping (B) -> C) -> (A) -> C { { f2(f1($0)) } }
var fn = (~add)(3) >>> (~multiple)(5) >>> (~sub)(1) >>> (~mod)(10) >>> (~divide)(2)
print(fn(1))

2. 面向协议编程

  • 优先考虑创建协议(接口),而不是父类(基类)
  • 优先考虑值类型(struct,enum),而不是引用类型(class),结构体不能被继承,而且接口体的调用方式比引用类型简单,被迫使用接口的方式编程
  • Swift支持协议扩展
  • 不要为了面向协议而面向协议

2.1 示例1

class Person {
    var name: String
    var age: Int
    init(_ name: String, _ age: Int) {
        self.name = name
        self.age = age
    }
}

struct MK<T> {
    var base: T
    init(_ base: T) {
        self.base = base
    }
}


extension String {
    var mk: MK<String> { MK(self) }
    static var mk: MK<String>.Type { MK<String>.self }
}
extension MK where T == String {
    var stringCount: Int {
        var count = 0
        for c in self.base where ("0"..."9").contains(c){
            count += 1
        }
        return count
    }
    
    static func run() {
        print("static run")
    }
}


extension Person {
    var mk: MK<Person> { MK(self) }
    static var mk: MK<Person>.Type { MK<Person>.self }
}

extension MK where T : Person{
    var personName: String {
        return self.base.name
    }
}

var str1: String = "MIke2345jing123"


print(str1.mk.stringCount)
String.mk.run()

var person = Person("Miqishu", 3)
print(person.mk.personName)

抽象之后

class Person {
    var name: String
    var age: Int
    init(_ name: String, _ age: Int) {
        self.name = name
        self.age = age
    }
}

class Student: Person {}

struct MK<T> {
    var base: T
    init(_ base: T) {
        self.base = base
    }
}

protocol MKCompatiable {}
extension MKCompatiable{
    var mk: MK<Self> {
        get {MK(self)}
        set {}
        
    }
    static var mk: MK<Self>.Type {
        get {MK<Self>.self}
        set {}
    }
}


extension String : MKCompatiable {}
extension MK where T == String {
    var stringCount: Int {
        var count = 0
        for c in self.base where ("0"..."9").contains(c){
            count += 1
        }
        return count
    }
    
    static func run() {
        print("static run")
    }
}


extension Person : MKCompatiable {}
extension MK where T : Person{
    var personName: String {
        return self.base.name
    }
    
    static func study() {
        print("static study")
    }
}

var str1: String = "MIke2345jing123"


print(str1.mk.stringCount)
String.mk.run()

var person = Person("Miqishu", 3)
print(person.mk.personName)


var stu = Student("jiaojiao", 10)
Student.mk.study()

如果NSStringNSMutableStringString都可以调用


var s1: String = "12345453534dsfsfsd"
var s2: NSString = "sa12312sdsds"
var s3: NSMutableString = "3123dsfsdf23"
print(s1.mk.stringCount)
print(s2.mk.stringCount)
print(s3.mk.stringCount)


extension String : MKCompatiable {}
extension NSString : MKCompatiable {}
extension MK where T : ExpressibleByStringLiteral {
    var stringCount: Int {
        var count = 0
        for c in self.base as! String where ("0"..."9").contains(c){
            count += 1
        }
        return count
    }
    
    static func run() {
        print("static run")
    }
}

2.2 示例2

利用协议实现类型判断


func isArray(_ value: Any) -> Bool {
    value is [Any]
}
 
print(isArray([1,2])) // true
print(isArray(["1",2])) // true
print(isArray(NSArray())) // true
print(isArray(NSMutableArray())) // true


protocol ArrayType {}
extension Array : ArrayType{}
extension NSArray : ArrayType{}
func isArrayType(_ type: Any.Type) -> Bool {type is ArrayType.Type}
print(isArrayType([Int].self)) // true
print(isArrayType([Any].self)) // true
print(isArrayType(NSArray.self)) // true
print(isArrayType(NSMutableArray.self))  // true

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值