您的位置:首页 > 移动开发 > Swift

swift函数式编程(高级)-闭包,协议,扩展,泛型,可空链

2016-01-08 12:01 477 查看
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)
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息