Swift 5.1 温故而知新笔记系列之第七天
Posted Deft_MKJing宓珂璟
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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()
如果NSString
、NSMutableString
、String
都可以调用
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
以上是关于Swift 5.1 温故而知新笔记系列之第七天的主要内容,如果未能解决你的问题,请参考以下文章