第七节 闭包二

2021-02-02  本文已影响0人  天明天

一.闭包的内存

1.闭包捕捉的num相当于 类的成员变量,闭包的方法,相当于类的实例方法。

typealias Fu = (Int) - > Int

func getFn() -> Fn {

//局部变量,这里会分配堆空间 便于下面的函数捕获他
 var num = 0

  func plus(_ v1 : Int) ->Int{
   num += v1
   return  num

 } 

 return plus

}  

var fn1 = getFn()
//打印普通变量地址,在这里含有函数,所以无法打印
print(Mens.ptr(ofVal: &fn1))
print(Mens.memStr(ofVal: &fn1))//打印普通对象内容

MemoryLayout.stride(ofValue: fn1)//占用多少字节
 //16 字节

这里注意内存地址与内存地址的存储内容的区别(类似于房间编号跟房间里的人的区别)

截屏2020-07-28 下午2.36.00.png

结论:

func getFn() -> Fn {

//局部变量,这里会分配堆空间 便于下面的函数捕获他
 var num = 0

  func plus(_ v1 : Int) ->Int{
   num += v1
   return  num
 } 

 num = 10
 return plus

}  

var fn1 = getFn()
print(fn1(1)) //打印结果是:11

注意:这里print(fn1(1)) //打印结果是:11。这里捕获的变量值是10,而不是0。捕获的时机是在return返回函数的时候

练习1.
截屏2020-07-28 下午3.28.28.png
这里:i << 1 相当于 i * 2

let (p,m) = getFuns()
print(p(6))   // (6,12)
print(m(5))  // (1,2)
print(p(3))  // (5,10)
print(m(2))  //(2,4)


截屏2020-07-28 下午3.48.27.png
练习2.
var funs : [() -> int] = []

for i in 1...3{

   funs.append { i } // 尾随闭包的简写
  /*
   相当于:

   func myFunc () -> Int {
   
        return i
}
funs.append{ myFunc}
*/
}

for f in funs {

print(''\(f())'')//打印的是函数 // 打印数值:1、2、3

}
类比: 截屏2020-07-28 下午4.04.47.png

2. 注意:

截屏2020-07-28 下午4.08.38.png

3. 自动闭包

截屏2020-07-28 下午4.17.31.png

如果这样写 getFirstPositive(_ v1:Int , _ v2: Int) -> Int{ return v1 > 0 ? v1 : v2}, 即使是v1 > 0, v2函数 仍然还是会调用。上面的写法是一种优化。

@autoclosure() 自动闭包:

截屏2020-07-28 下午4.24.45.png 截屏2020-07-28 下午6.27.42.png
上一篇下一篇

猜你喜欢

热点阅读