Unity 函数与闭包实例

全局变量和局部变量作用域

本文的重点重在讨论闭包,提及到闭包,还是有必要先来回顾下变量的作用域和生命周期。

在c#的语法里, 变量的作用域通常有大体上分为两类,全局变量局部变量。更细致的区分类型又可分为全局变量静态全局变量局部变量静态局部变量。通常把在类级别声明的变量看作字段(全局变量),而把方法级别声明的变量看作局部变量。

很好的帮助理解全局变量和局部变量就来看上图的例子,class的变量variable与function的变量variable是不会发生作用域的冲突的。

全局变量和局部变量生命周期

类里声明的全局变量是随着类的实例化而存在的,同时伴随着对象的资源回收而消亡(注:这里不包含非实例化的static和const对象)。而函数体内(或代码片段)的局部变量也伴随着函数的调用而开始创建,在函数调用结束而自动GC释放内存空间,它的变量的生命周期销毁满足先进后出的栈的特性。

闭包

怎么来理解闭包呢?初次听到这个概念时的确难以渗透其字面意思。闭包的概念定义如下:闭包是指有权访问另一个函数作用域中的变量的函数。

闭包本就指的就是一种函数,创建这样的特殊函数发生的场景在于在一个函数中创建另一个函数的情形

闭包分析

下面是一段简短的代码,来看看其运行结果。

首先来说明下,Func是.NETFramework 3.5中,提供的delegate定义方式,省去了常规的delegate需要先委托声明的过程,调用传入参数只需Func()(args)。与此类似的还有一个Action。

如果方法有返回值,就使用Func,或者Func<>

如果方法没有返回值,则使用Action,或者Action<>

分析上面的执行过程。首先执行的是Start()函数中调用的TestFunction()函数。

1).TestFunction()函数内定义了val变量和一个用lamdba表达式创建的委托_function。初次执行_function() ,函数内容为10 + 10,输出result1的结果为20。

2).接着val的值被改成30,再次以相同的参数执行_function() ,函数内容为 10 + 30,输出result2的结果为40。

3).最后是执行到return _function,外部参数以40输入,此时的val已经是被修改成了最后的执行的30,最后的函数内容为 40 + 30,输出最终的result3的结果为70。

回顾整个调用过程,val最为一个局部变量,它的生命周期本应该TestFunction()执行完毕后就结束的,之所以对之后的结果产生了影响,其实就是发生了所谓的闭包。

再次将代码调用等价变形有。

这是接近于编译器的生成代码,编译器创建了一个匿名类,这个匿名类通常存在于与TestFunction()在同一个类中,并在TestFunction()中创建它的实例,局部变量实际上是作为匿名类中的字段存在的。

未经允许不得转载:第一Unity3D » Unity 函数与闭包实例

赞 (0)