什么时候使用闭合? [英] When to use closure?

查看:116
本文介绍了什么时候使用闭合?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经看到过关闭的示例 - 什么是关闭?

任何人都可以提供简单的例子来说明何时使用闭包?





假设语言没有关闭支持,那么如何实现类似的东西呢?



不要冒犯任何人,请用像c#,python,javascript,ruby等语言发布代码示例。
对不起,我还不懂功能语言。 p>

解决方案

关闭是很好的工具。什么时候使用?任何时候你喜欢...正如已经说过的,替代方法是写一个类;例如,pre C#2.0,创建参数化线程是一个真正的斗争。使用C#2.0你甚至不需要'ParameterizedThreadStart'你只需要做:

  string name = // blah 
int value = // blah
new Thread((ThreadStart)delegate {DoWork(name,value);}); //或inline if short

与创建具有名称和值的类比较



或者搜索列表(此时使用lambda):

  Person person = list.Find(x => x.Age> minAge&& x.Region == region); 

再次 - 替代方法是编写一个具有两个属性和一个方法的类:

  internal sealed类PersonFinder 
{
public PersonFinder(int minAge,string region)
{
this.minAge = minAge;
this.region = region;
}
private readonly int minAge;
private readonly string region;
public bool IsMatch(Person person)
{
return person.Age> minAge&& person.Region == region;
}
}
...
person person = list.Find(new PersonFinder(minAge,region).IsMatch);

这是相当于编译器在引擎盖下实际上,它使用公共读/写字段,而不是私有readonly)。



C#捕获的最大警告是观察范围;例如:

  for(int i = 0; i <10; i ++){
ThreadPool.QueueUserWorkItem delegate
{
Console.WriteLine(i);
});
}

这可能不会打印你期望的,因为 em> i用于每个。你可以看到重复的任何组合 - 甚至10 10。您需要仔细地在C#中捕获变量:

  for(int i = 0; i <10; i ++){
int j = i;
ThreadPool.QueueUserWorkItem(delegate
{
Console.WriteLine(j);
});
}



这里每个j都被单独捕获(即不同的编译器生成的类实例)



Jon Skeet有一个很好的博客文章,涵盖C#和java闭包这里;或者有关详情,请参阅他的书深入C#,其中有一整章。 / p>

I have seen samples of closure from - What is a 'Closure'?

Can anyone provide simple example of when to use closure?

Specifically, scenarios in which closure makes sense?

Lets assume that the language doesn't have closure support, how would one still achieve similar thing?

Not to offend anyone, please post code samples in a language like c#, python, javascript, ruby etc.
I am sorry, I do not understand functional languages yet.

解决方案

Closures are simply great tools. When to use them? Any time you like... As has already been said, the alternative is to write a class; for example, pre C# 2.0, creating a parameterised thread was a real struggle. With C# 2.0 you don't even need the `ParameterizedThreadStart' you just do:

string name = // blah
int value = // blah
new Thread((ThreadStart)delegate { DoWork(name, value);}); // or inline if short

Compare that to creating a class with a name and value

Or likewise with searching for a list (using a lambda this time):

Person person = list.Find(x=>x.Age > minAge && x.Region == region);

Again - the alternative would be to write a class with two properties and a method:

internal sealed class PersonFinder
{
    public PersonFinder(int minAge, string region)
    {
        this.minAge = minAge;
        this.region = region;
    }
    private readonly int minAge;
    private readonly string region;
    public bool IsMatch(Person person)
    {
        return person.Age > minAge && person.Region == region;
    }
}
...
Person person = list.Find(new PersonFinder(minAge,region).IsMatch);

This is fairly comparable to how the compiler does it under the bonnet (actually, it uses public read/write fields, not private readonly).

The biggest caveat with C# captures is to watch the scope; for example:

        for(int i = 0 ; i < 10 ; i++) {
            ThreadPool.QueueUserWorkItem(delegate
            {
                Console.WriteLine(i);
            });
        }

This might not print what you expect, since the variable i is used for each. You could see any combination of repeats - even 10 10's. You need to carefully scope captured variables in C#:

        for(int i = 0 ; i < 10 ; i++) {
            int j = i;
            ThreadPool.QueueUserWorkItem(delegate
            {
                Console.WriteLine(j);
            });
        }

Here each j gets captured separately (i.e. a different compiler-generated class instance).

Jon Skeet has a good blog entry covering C# and java closures here; or for more detail, see his book C# in Depth, which has an entire chapter on them.

这篇关于什么时候使用闭合?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆