swift函数式编程实际是非常灵活的,在函数的高级应用中,实际上还包括了闭包,协议,泛型等等oc中没有的概念,按照顺序介绍这些概念和应用。
一:闭包
闭包实际就是objective-c中的block,其实际就是定义一个函数体,并将其作为参数传递,它既可以是有名的,也可以是匿名的函数
1.1 闭包的定义和声明
闭包其本质就是将一个函数体作为变量或者常量,然后将函数体进行传递或者调用。函数的嵌套其实也是一种闭包。但是函数是不能捕捉上下文的,但是闭包可以。这是他们之间的一个大区别!!!!
var transform:(Int)->Int = {//定义一个变量闭包
(number:Int)->Int in//定义参数,申明参数列表和返回值
if number%2 == 0{
return number * 3
}else{
return 0
}
}
transform = {
(number:Int)->Int in
return 0
}
func transform1(a:Int)->Int{
return 1
}
var numbers = [2,53,3,7,8,3];
numbers.map(transform)//可以传递闭包,内部调用闭包,闭包的函数体才会执行。
numbers.map(transform1)//可以传递函数
transform(6)//必须调用,才会执行函数体
print(numbers.map(transform))
var tempNum = numbers.map {
(number:Int) -> Int in
if number%2 == 0{
return number * 3
}else{
return 0
}
}
print(tempNum)
1.2闭包的值捕获,跟block一样,闭包虽然类似于定义一个函数体的变量,但是闭包内部可以捕获上下文的值。
func factoria(factor:Int)->Int{//顶一个计算阶乘的函数
var total = 1
if(factor<=0){
return total
}
for item in 1...factor{
let mutiple:()->Int = {
total = total*item//内部捕获了函数体外部的total值和item值,函数是不能捕捉上下文的。这是他们的一个大区别!!!!
return total
}
mutiple()// 调用闭包函数体
}
return total
}
factoria(3)//打印结果是6
二:协议(swift中的协议跟objective-c中的协议有很大区别,objective-c中的协议用于代理,而swift中的协议更像是Java中的抽象类)
2.1协议的申明和定义已经实现
protocol Continer{//申明协议
typealias ItemType//申明类型
func apped(item:ItemType)//申明方法
var count:Int{get}//只读
subscript(i:Int)->ItemType{get}//只读
}
class IntArray:Continer {//实现协议
var array = [Int]()
typealias ItemType = Int
func apped(item: ItemType) {
array.append(item)
}
var count : Int{
return array.count
}
subscript(i:Int)->Int{
return array[i]
}
}
如果一个类实现了一个协议,就必须实现这个协议的所有方法和属性。
2.2 组合协议(实现了多个协议)
//组合协议
func allFunc(target:protocol<SomeProtocol,OtherProtocol>){//这个函数的参数是实现了所有这些协议的实例对象
target.someFunc()
target.otherFunc()
}
protocol SomeProtocol{
func someFunc()->()
}
protocol OtherProtocol{
func otherFunc()->()
}
class All:SomeProtocol,OtherProtocol {//类All实现了这2个协议
func someFunc() {
print("someFunc")
}
func otherFunc() {
print("oher")
}
}
var all = All()
allFunc(all)
三:扩展(与objective-c中的分类相似,可以扩展类的方法)
extension Array{
func contains(comparator:(Int)->Bool,value:Int)->Bool{//扩展了Array的一个新方法,参数可以传递闭包或者一个函数
for item in self{
if(comparator(value)){//在这里调用闭包
return true
}
}
return false
}
}
numbers = [1,2,3]
print(numbers)
numbers.contains(//在这里申明闭包
{
(element:Int) -> Bool in//传递的是闭包,必须写参数列表和返回值
for item in numbers{
if element == item{//判读闭包的参数值有没有跟数组中的值相同的。
return true
}
}
return false
}, value: 5)
print(numbers)
四.泛型,泛型也是objective-c中特有的,它可以不指定类型,可以代表任何的类型
//泛型函数
func removeLast<T>(inout array:Array<T>){//泛型函数中,必须在函数名之后先申明泛型
array.removeLast()
}
var array = [1,2,3,4]
removeLast(&array)
//泛型类型
class GenericTest<T>{//泛型类型是在类的定义是先申明泛型,但是在类实例化的时候必须知道泛型的具体类型
var objects = [T]()
}
//实例化的时候,必须指定泛型类型
var buffer1 = GenericTest<String>()
buffer1.objects += ["1","2","3"]
print(buffer1.objects)
var buffer2 = GenericTest<Int>()
buffer2.objects += [1,2,3]
print(buffer2.objects)
五:可空链(类似于强制拆箱,但不是强制拆箱,它能保证数据安全)
注意:可空链上如果存在着非可空的类型,它会自动装包成可空的类型。
class Outer {
var inner:Inner?
}
class Inner {
var innerInner:InnerInner?
}
class InnerInner {
var innerMostStr:String = ""
}
var outerOptional : Outer?
var inner : Inner?
var innerInner:InnerInner?
outerOptional = Outer()
inner = Inner()
innerInner = InnerInner()
innerInner?.innerMostStr = "123"
inner?.innerInner = innerInner
outerOptional?.inner = inner
print(outerOptional)
print(innerInner)
if (outerOptional?.inner?.innerInner?.innerMostStr != nil){//可空链上任何一个为空,则整个可空链都返回空(nil)
print(outerOptional?.inner?.innerInner?.innerMostStr)//可空链中如果有非可空的参数,会自动装包
}else{
print(outerOptional?.inner?.innerInner?.innerMostStr)
}
//可空链的应用
class Student{
var course = [SchoolCourse]()
subscript(i:Int)->SchoolCourse{
return course[i]
}
func numberOfCourse()->Int{
return course.count
}
func addCourse(c:SchoolCourse){
course .append(c)
}
}
class SchoolCourse {
var departMent:Department = Department()
let couseName : String
init(name:String){
couseName = name
}
func printCourseDescription(){
if let departmentDescrip = departMent.departmentDescription(){
print("\(self.couseName) is part of \(departmentDescrip)")
}else{
print(self.couseName)
}
}
}
class Department {
var departName : String?
var collegeOf:String?
func departmentDescription()->String?{
if departName != nil{
return departName;
}else if collegeOf != nil{
return collegeOf
}else{
return nil
}
}
}
let student = Student()
student.addCourse(SchoolCourse.init(name: "math"))
student.numberOfCourse()
let OptionalStudent : Student? = Student()
OptionalStudent?.numberOfCourse()
let student1 = Student()
let mathCourse = SchoolCourse.init(name: "math")
let mathDepartment = Department()
mathDepartment.departName = "Math Departhment"
mathCourse.departMent=mathDepartment
student1.addCourse(mathCourse)
let optionalStudent1 : Student? = student1
let longChain = optionalStudent1?[0].departMent.departmentDescription()
print(longChain)
print(optionalStudent1?[0].departMent)//默认会装包
//要么返回的是nil,要么返回的是optional(x)