我有一个大约十行代码的方法.我想创建更多完全相同的方法,除了一个会改变一行代码的小计算.这是传递函数指针以替换该行的完美应用程序,但Java没有函数指针.什么是我最好的选择?
Python nonlocal语句做了什么(在Python 3.0及更高版本中)?
官方Python网站上没有文档,help("nonlocal")也没有用.
我通过返回一个内部函数得到它,它将有权访问其直接父级中定义的任何变量.
这对我有用吗?也许我还没有完全了解它.我在网上看到的大多数例子都没有提供任何现实世界的代码,只是模糊的例子.
有人能告诉我现实世界中使用的闭包吗?
比如这个吗?
var warnUser = function (msg) {
var calledCount = 0;
return function() {
calledCount++;
alert(msg + '\nYou have been warned ' + calledCount + ' times.');
};
};
var warnForTamper = warnUser('You can not tamper with our HTML.');
warnForTamper();
warnForTamper();
Run Code Online (Sandbox Code Playgroud) 最近我开始玩Python,我遇到了一些特殊的闭包方式.请考虑以下代码:
adders=[0,1,2,3]
for i in [0,1,2,3]:
adders[i]=lambda a: i+a
print adders[1](3)
Run Code Online (Sandbox Code Playgroud)
它构建了一个简单的函数数组,它接受单个输入并返回由数字添加的输入.函数在for循环中构造,迭代器i从中循环0到3.对于这些数字中的每一个,lambda都会创建一个函数i,该函数捕获并将其添加到函数的输入中.最后一行将第二个lambda函数3作为参数调用.令我惊讶的是输出结果是6.
我期待一个4.我的理由是:在Python中,一切都是一个对象,因此每个变量都是指向它的指针.在创建lambda闭包时i,我希望它存储一个指向当前指向的整数对象的指针i.这意味着当i分配一个新的整数对象时,它不应该影响先前创建的闭包.遗憾的是,adders在调试器中检查数组表明它确实存在.所有的lambda功能指的最后一个值i,3,这将导致adders[1](3)返回6.
这让我想知道以下内容:
lambda函数以更改其值i时不会受到影响的方式捕获当前i值?我已经在Python中看到并使用了嵌套函数,它们与闭包的定义相匹配.那他们为什么叫nested functions而不是closures?
嵌套函数是不是闭包,因为它们不被外部世界使用?
更新:我正在阅读关于闭包的内容,这让我想到了关于Python的这个概念.我在下面的评论中搜索并找到了某人提到的文章,但我无法完全理解该文章中的解释,所以这就是我提出这个问题的原因.
我有以下代码片段.
function addLinks () {
for (var i=0, link; i<5; i++) {
link = document.createElement("a");
link.innerHTML = "Link " + i;
link.onclick = function () {
alert(i);
};
document.body.appendChild(link);
}
}
Run Code Online (Sandbox Code Playgroud)
上面的代码用于生成5个链接,并使用alert事件绑定每个链接以显示当前链接ID.但它不起作用.当您单击生成的链接时,他们都会说"链接5".
但是以下代码片段可以满足我们的期望.
function addLinks () {
for (var i=0, link; i<5; i++) {
link = document.createElement("a");
link.innerHTML = "Link " + i;
link.onclick = function (num) {
return function () {
alert(num);
};
}(i);
document.body.appendChild(link);
}
}
Run Code Online (Sandbox Code Playgroud)
以上两个片段均引自此处.正如作者的解释,似乎关闭使魔术.
但它是如何工作的以及闭包如何使其工作都超出了我的理解范围.为什么第一个不工作而第二个工作?任何人都可以详细解释这个魔法吗?
谢谢.
我遇到了一个关于C#的有趣问题.我有如下代码.
List<Func<int>> actions = new List<Func<int>>();
int variable = 0;
while (variable < 5)
{
actions.Add(() => variable * 2);
++ variable;
}
foreach (var act in actions)
{
Console.WriteLine(act.Invoke());
}
Run Code Online (Sandbox Code Playgroud)
我希望它输出0,2,4,6,8.但是,它实际输出5个10.
似乎是由于所有操作都涉及一个捕获的变量.结果,当它们被调用时,它们都具有相同的输出.
有没有办法解决这个限制,让每个动作实例都有自己的捕获变量?
什么是关闭?我们在.NET中有它们吗?
如果它们确实存在于.NET中,您能否提供一个代码片段(最好用C#)来解释它?
编辑:我浏览了Jon Skeet的文章,了解什么是闭包以及如何在.NET中使用它们.
是否可以使用递归和匿名的PHP函数?这是我试图让它工作,但它没有传递函数名称.
$factorial = function( $n ) use ( $factorial ) {
if( $n <= 1 ) return 1;
return $factorial( $n - 1 ) * $n;
};
print $factorial( 5 );
Run Code Online (Sandbox Code Playgroud)
我也知道这是实现阶乘的一种不好的方法,它只是一个例子.
使用实例方法作为事件处理程序的回调改变的范围this从"我的实例"到"无论只是调用的回调".所以我的代码看起来像这样
function MyObject() {
this.doSomething = function() {
...
}
var self = this
$('#foobar').bind('click', function(){
self.doSomethng()
// this.doSomething() would not work here
})
}
Run Code Online (Sandbox Code Playgroud)
它有效,但这是最好的方法吗?这对我来说很奇怪.