zoukankan      html  css  js  c++  java
  • 闭包

    1.闭包是自包含的功能代码块,可以在代码中使用或者用来作为参数传值。

    2.闭包可以捕获和存储上下文中定义的的任何常量和变量的引用。这就是所谓的变量和变量的自封闭,

    3.因此命名为”闭包“("Closures)").Swift还会处理所有捕获的引用的内存管理。

    如何接收一个函数

    // (Int,Int)-> Int
    func add(a: Int,b: Int) -> Int {
        return a + b
    }
    //   (Int,Int) -> Int
    func multi(a: Int,b: Int) -> Int {
        return a * b
    }
    
    //语法(Int,Double)-> 返回类型
    var f2: (Int,Int)-> Int = add
    f2(1,2)
    f2 = multi
    f2(1,2)

    用一个函数(processArray)实现接口(ProceesInt),实现接口(proceesInt)的类经过函数的筛选得到结果

    目的:为了让一个函数拥有多种功能

    如何去实现:利用了一个接口

    func processArray() ->[Int] {
        let array = [1,8,7,3]
        var result:[Int] = []
        for item in array{
            if item % 2 == 0  {
                result.append(item)
            }
        }
        return result
    
    }
    
    
    func processArray2(chulizhe: ProcessInt) ->[Int] {
        let array = [1,8,7,3]
        var result:[Int] = []
        for item in array{
            if chulizhe.guolv(item) {
                result.append(item)
            }
        }
        return result
    
    }
    protocol ProcessInt {
        func guolv(data: Int)->Bool
    }
    class DaYuYi: ProcessInt {
        func guolv(data: Int)->Bool{
            return data > 1
        }
    } //实现了筛选大于一的数
    class OuShu: ProcessInt {
        func guolv(data: Int)->Bool{
            return data % 2 == 0
        }
    } //实现了筛选偶数
    processArray2(OuShu())

    在函数里传一个函数

    func xxx(a: (Int)->Int,b: Int) -> (Int)-> Int {
        func innerXX(a: Int) -> Int {
            return 5
        }
        return innerXX
    }
    func p(a: Int) -> Int {
        return 10
    }
    let re = xxx(p,b:11)
    re(6)    //和下面的情况是一样的,都是返回5
     xxx(p,b:11)(7)

    传一个函数取偶数

    func processArray(suanfa: (Int)->Bool) ->[Int] {
        let array = [1,8,7,3]
        var result:[Int] = []
        for item in array{
            if suanfa(item) {
                result.append(item)
            }
        }
        return result
        
    }
    func process(source: Int) -> Bool {
        return source % 2  == 0
    }
    let result = processArray(process)
    result

    用闭包来完成传函数的功能

    func processArray(suanfa: (Int)->Bool) ->[Int] {
        let array = [1,8,7,3]
        var result:[Int] = []
        for item in array{
            if suanfa(item) {
                result.append(item)
            }
        }
        return result
        
    }
    
    let result = processArray({
        (a: Int) -> Bool in
        return a % 2 == 0
    })
    
    result

    利用函数来实现排序的功能

    let array = [1,2,8,3,9]
    func compare(a: Int,b: Int ) -> Bool {
        return a < b
    }
    array.sort(compare)

    利用闭包来传值

    let array = [1,2,8,3,9]
    
    //传闭包表达式,不需要额外定义函数
    let result2 = array.sort({(a: Int,b: Int)->Bool in return a > b })
    result2

    闭包的优化

    let array = [1,2,8,3,9]
    
    
    //参数类型与返回类型的推断
    let result2 = array.sort({(a,b) in return a > b })
    result2
    
    //单行代码自动会返回此代码的结果
    let result3 = array.sort({(a,b) in  a > b })
     result3
    //自动提供简短的参数名 $0,$1,$2....
    //
    let result4 = array.sort({$0 > $1 })
    result4
    
    //如果一个函数(sort),它只有一个参数,此参数的类型是函数类型,那么可以把大括号中得内容
    //放到小括号外面
    let result5 = array.sort(){
        $0 > $1
    }
    result2
    //或者 :此时是可以去掉括号的
    let result6 = array.sort{$0 > $1}
    result5

    闭包的捕获值

    func funcFactory() ->() ->Int {
        var total = 0
        
        func innerFunc() -> Int {
            total = total + 1
            return total
        }
        return innerFunc
        
    }
    let r1 = funcFactory() 
    r1() //捕获上面r1的值 输出1
    r1()
    
    let r2 = funcFactory()
    r2()
    r2()
    let r3 = r2
    r3()//这两行代码能部分说明其是一个引用的类型

    1.自动把一段代码转换为闭包

    2.没有任何参数

    3.调用时返回的是整个表达式的值

    4.自动闭包一定是作为函数的参数

    5.闭包参数添加@autoclosure

    func autoClosureDemo2(@autoclosure x:()->String) {
        let result = x()
        print(result)
    }
    
    autoClosureDemo2("a")

    闭包的另一种用法,可以直接给函数类型赋值。

    let f4:()-> Int = {5}  //{5}是一个闭包,经过了一系列的优化后,变成了{5}
    f4() // 返回5

     在类里的,在控制台输出5

    class XX {
        var i = 5
        //闭包要用到类里面的实例成员,必须加self或者额外声明变量(内存管理时在阐述)
        
        //
        lazy var close: ()->Void = {
            print(self.i)
        }
    }
    
    XX().close()
  • 相关阅读:
    uip源码剖析【三】——【网络层】ICMP解读
    uip源码剖析【五】——【传输层】TCP解读
    WebGame方案汇总
    终于,我生命中第一次编译并运行了手机程序
    使用R7版NDK搭建Android开发环境[不使用Cgywin]
    拷问Unity:开发U3D游戏要思考的问题
    浏览器缓存导致FLASH资源更新问题的解决方案
    山寨版的《KingdomRush(皇城突袭)》
    在Unity3D的网络游戏中实现资源动态加载
    Unity3d之无缝地形场景切换–解决方法和代码
  • 原文地址:https://www.cnblogs.com/kangniuniu/p/4972844.html
Copyright © 2011-2022 走看看