当前位置:网站首页>闭包问题C# Lua
闭包问题C# Lua
2022-06-26 06:21:00 【ThomasQxx】
闭包问题汇总(之前有个大佬时不时问几个问题,现在来总结下经验)
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class ToggleTest : MonoBehaviour
{
public Toggle[] toggles;
private void Start() {
for (int i = 0; i < toggles.Length; i++)
{
toggles[i].onValueChanged.AddListener((isOn)=>OnToggleChanged(isOn,i));
}
}
private void OnToggleChanged(bool isOn,int index){
Debug.Log($"index==>{
index}..State===>{
isOn}");
}
}
看到这里可以先猜猜选择Toggle打印结果会是多少?Toggle单选按钮有三个。
可以看到Index始终为3。。。
为什么结果会是3呢?这里就会提到闭包这个概念:内层的函数可以引用包含在它外层的函数的变量,即使外层函数的执行已经终止。但该变量提供的值并非变量创建时的值,而是在父函数范围内的最终值。正常来讲For循环执行完毕的时候i变量的内存会随着For循环结束而结束生命。但是由于匿名函数引用了i,导致i不能随For循环结束而结束。所以这个时候i=3.当我们执行点击的时候index=3.这里问题就找到了,那么应该如何解决呢?
解决方案

这样就解决了。想要弄清楚解决的思路,还是得从内存谈起。上一张没有int t = i的代码中。i有几个内存地址呢?可以看出来i只有一个内存地址。而当前图中t有几个内存地址呢?很明显有三个,每次For循环进来都会声明一个t的内存地址。并且t的值随着For循环结束都是不同的。分别是0,1,2。所以问题到这里就可以完全理解了。

Lua中的闭包
function newCounter()
local i = 0
return function()
i = i + 1
return i
end
end
c1 = newCounter()
print(c1())
print(c1())
结果应该是1,2.i本来应该在NewCounter调用结束时候就随之释放内存。但是由于内部函数引用,所以内存继续存在,第一次执行完c1()i = 0+1 = 1;第二次执行c1()完i就应该为i = 1+1 =2;
function newCounter()
local i = 0
return function()
i = i + 1
return i
end
end
c1 = newCounter()
print(c1())
c1 = nil
c2 = newCounter()
print(c2())
结果应该是1,1.因为第一次执行完c1()i = i + 1 = 0 + 1 = 1;但是接下来c1=nil等于释放了内存。c2 = newCounter() 执行c2()时候这个时候i为0.所以c2()结果为i = i + 1 = 0 + 1 = 1;所以最终结果为1,1.
边栏推荐
- Gof23 - builder mode
- 100 cases of go language
- How can an enterprise successfully complete cloud migration?
- Zotero文献管理工具之Jasminum(茉莉花)插件
- 温度报警器
- Redis multithreading and ACL
- Logstash——Logstash将数据推送至Redis
- Underlying principle of MySQL index
- Work accumulation - problems encountered in using ThreadLocal in web requests
- MySQL-05
猜你喜欢

Message queue - function, performance, operation and maintenance comparison

MVC source code sharing

Data visualization practice: Experimental Report

GoF23—抽象工厂模式

Logstash——Logstash将数据推送至Redis
Web components series (10) -- realize the basic layout of mycard

canal部署、原理和使用介绍

Logstash - logstash pushes data to redis

消息队列-消息事务管理对比

Typora activation method
随机推荐
PyTorch使用多GPU并行训练及其原理和注意事项
自顶向下的变成方法
Logstash - logstash pushes data to redis
Prometheus和Zabbix的对比
在web页面播放rtsp流视频(webrtc)
连接数服务器数据库报:错误号码2003Can‘t connect to MySQL server on ‘服务器地址‘(10061)
Failed to configure a DataSource: ‘url‘ attribute is not specified and no embedded datasource could
MYSQL索引不生效的原因
China micronutrient market trend report, technical innovation and market forecast
Work accumulation - problems encountered in using ThreadLocal in web requests
Tortoise and rabbit race example
Handwritten background management framework template (I)
API and encapsulation of cookies
浏览器的四大内核:Trident,Gecko,Webkit,Blink
volatile应用场景
Introduction to the use of TS generics in functions, interfaces and classes
Usage of zip (*arg)
Experience the new features of Milvus 2.0 together
TCP连接与断开,状态迁移图详解
TCP connection and disconnection, detailed explanation of state transition diagram