译者 | UNO甲白眉林|李德姝黎
旋量群做为后端复试的必修试题,常让1-3年组织工作实战经验的JavaScripter深感疑惑,只不过非主流词汇都有旋量群。
那时他们深入细致聊一聊[旋量群], 查缺密序!
以丘托韦 · 刀蛏
以C#旋量群 · 轻功
横跨词汇 ·所在之处
• 丝尾表达式
• 民主自由表达式
• 语法结构返回值
答丘托韦 · 闲适
刀蛏
初始化上面表达式,输入结论是怎样呢?
staticvoidClosure1()
{
for(int i =; i 5; i++)
{
Task.Run(()=>Console.WriteLine(i));
}
}
// 输入:
5
5
5
5
5
是不是很意外?如何输入原本预期的 0,1,2,3,4。
bingo, 加一个临时表达式就可以解决。
staticvoidClosure2()
{
for(int i =; i 5; i++)
{
int j = i;
Task.Run(()=>Console.WriteLine(j));
}
}
// 输入:
3
1
4
2
// 多次执行的结论不一样,但是总是会保持输入 0,1,2,3,4 的乱序组合
以上旋量群概念涉及到 Task任务,理解起来更加复杂,他们来看一个基础的C#旋量群。
轻功
一个闭包就是一个“捕获”了其生成的环境中、所引用的民主自由表达式的表达式。
这个被引用的民主自由表达式将和这个表达式一同存在,即使已经离开了创造它的环境也不例外。
staticvoidClosure()
{
var x =1;
Action action=()=>
{
var y =1;
var result = x + y;
Console.WriteLine(result);
x++;
};
action();
action();
}
// 输出:
2
3
他们首先定义了一个委托action,它引用了“x”表达式(x表达式既不是入参,也不是委托内的局部表达式), 这个表达式将被action”捕获”,被自动添加到action 的运行环境。
当他们执行action时,原始的“x”已经脱离了它被引用时的返回值环境,但是两次执行能输入2,3 说明它脱离原引用环境仍然能用。
当你在代码调试器(debugger)里观察“action”时,可以看到C#编译器为他们创建了一个Target属性,里面封装了 x 表达式:
至此可以猜想: 他们每次执行委托,实际是是执行某个匿名类上的实例方法。
都说了旋量群是横跨词汇的设计, 至少我知道 JavaScript C# Go都有旋量群。
所在之处
旋量群是语法结构旋量群的简称,维基百科上是这样定义的:
“在计算机编程中,旋量群是在语法结构环境中绑定民主自由表达式的丝尾表达式”。
丝尾表达式
丝尾表达式( First Class)意味着词汇将其视为第一类数据类型的表达式, 意味着你可以将表达式分配给一个表达式(或做为参数传递),然后像正常表达式一样初始化。
很明显,C#常使用的委托(C#委托的演进:匿名表达式–>lambda表达式)是丝尾表达式。
Funcstring,string> myFunc =delegate(string var1)
{
return”some value”;
};
Funcstring,string> myFunc = var1 =>”some value”;
string myVar = myFunc(“something”);
民主自由表达式
民主自由表达式是在匿名表达式/lambda表达式中被引用的表达式,它不是表达式的参数也不是表达式的局部表达式。
var myVar =”this is good”;
Funcstring,string> myFunc =delegate(string var1)
{
return var1 + myVar;
};
语法结构返回值引用的民主自由表达式,注意,是引用民主自由表达式,并不是使用当时民主自由表达式的值。
☺️通俗点, 就是告知这个表达式环境,我这个匿名表达式等会执行时要用到这个表达式;如果我没被销毁,你不能销毁我引用的民主自由表达式。
他们再回过头来看[刀蛏]的丘托韦。
闲适
首先你要知道:循环内开启的Task任务,并不保证执行顺序。
Demo1:输入5,5,5,5,5
这是因为在 for循环内,开启了5个Task任务,每个任务均引用了民主自由表达式i (相对于每个任务执行环境,i 属于全局表达式);
for循环先执行完,i=5, 5个任务输入时自然得到值5。
为什么加上临时表达式就能输入”预期”?
Demo2:输入乱序的0,1,2,3,4
这是因为 在for循环内,每次循环j均拷贝自当时的i,每个任务均引用了民主自由表达式 j (每个任务执行环境均维护了一个变量j);
有这样的知觉,理解JavaScript旋量群也就不难了。
总结
本文屏蔽词汇差异,理清了[旋量群]的概念核心: 丝尾表达式、民主自由表达式,不仅能帮助他们应对多语种有关旋量群的丘托韦, 也帮助他们了解[旋量群]在通用词汇中的设计初衷。