何时使用闭包

发布于 2024-11-16 06:37:38 字数 493 浏览 0 评论 0原文

请跳到下面的“问题”

注意:如果您只是想跳过上下文, 通常我会说“等到我向你展示 for 理解”,然后我展示如何将 for 理解归结为使用 flatMap/map + 闭包。

这个例子确实有帮助,但是对我来说很难解释一般性的“这是你认识到何时使用闭包的时候”。这是你在函数式编程中“刚刚习惯”的事情之一,你几乎不假思索地做到了。

通常,当我谈论 Scala 时,我正在与 Java 开发人员交谈,想到的一个类比是“你知道当你创建一个匿名内部类时,它需要访问该类定义位置之上的某个变量吗?这就像一个闭包”。因此,我使用事件回调处理作为一个特定示例(因为在这种情况下不可避免地会使用匿名内部类)。

考虑到观众(没有经验,或对 FP 的经验有限),我不会继续讨论像 Monad 这样的术语,这些人通常会寻找与他们相关的具体/实用的示例。

问题: 任何人都有自己的成功解释闭包的方法,这对 Java(或其他 OO 语言)开发人员来说确实很重要吗?

Note: jump down to "Question" below if you just want to skip the context

When giving talks on Scala I'm almost always certain I'll be asked "but when would you use a Closure?" Typically I say "wait until I show you a for comprehension" and then I show how the for comprehension can be boiled down to using flatMap/map + closures.

This example does help, however it's tough for me to explain a general "this is when you'd recognize when to use a closure". It's one of those things you "just get used to" in functional programming, you almost do it without thinking.

Typically I'm talking to Java devs when I speak about Scala, and one analogy that comes to mind is "you know when you create an anonymous inner class that needs to access a variable somewhere above where the class was defined? That's like a closure". So I use event call-back processing as one particular example (as inevitably you use anonymous inner classes in that scenario).

Considering the audience (no experience, or limited experience with FP) I don't go on to discuss terms like Monads, these people are typically looking for concrete/pragmatic examples they can relate to.

Question:
Anyone have their own way of successfully explaining closures that really hits home for Java (or other OO language) developers?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

过期情话 2024-11-23 06:37:38

许多 Java 开发人员已经熟悉“closures-lite” - 用类模仿闭包的设计模式:

  • 访问者
  • 命令
  • 策略
  • 函子(请参阅 Google Guice 的集合处理以获取许多示例)
  • 回调/侦听器(大量 Swing)

每当 Java 开发人员达到对于解决 Scala 中的问题的这些模式之一,他们应该考虑将闭包作为一种轻量级替代方案。

正如您所提到的,一流的闭包在某些方面只是这些模式的逻辑扩展 - 如果我的匿名类只有一个方法,为什么不完全废除该类,而只拥有该方法本身呢?

也许还值得讨论所有这些模式的共同点 - 它们都是某种形式的控制流抽象。它们将控制流本身与在该流中的某些点执行的操作分开。任何类似的关注点分离都可以从闭包中受益。

Many Java developers will already be familiar with 'closures-lite' - design patterns that imitate closures with classes:

  • visitor
  • command
  • strategy
  • functor (see Google Guice's collections handling for many examples)
  • callback/listener (large swathes of Swing)

Whenever a Java developer reaches for one of these patterns to solve a problem in Scala, they should be considering closures as a lightweight alternative.

As you mention, first-class closures are in some ways just a logical extension of these patterns - if my anonymous class only has one method, why not do away with the class altogether, and just have the method itself?

It may also be worth discussing what all of these patterns have in common - they are all some form of abstraction of control flow. They separate control flow itself from an action to perform at certain points in this flow. Any similar separation of concerns can benefit from closures.

野心澎湃 2024-11-23 06:37:38

为什么不颠倒演示顺序呢?当您通常呈现闭包时,呈现一种众所周知的模式(例如侦听器或访问者)。然后展示闭包如何在不创建额外的“辅助”对象或不必要的代码框架的情况下解决问题。

您说您的听众正在寻找闭包如何工作的具体示例。在展示其中一些之后,您可以后退并正确定义闭包。提出问题、解决问题、再次解决问题、再次解决问题,然后提出更大的理论的技术对于程序员来说并不陌生。这就是他们最初发现模式的方式。

Why don't you reverse the order of presentation? When you would normally present Closures, present a well known pattern (like Listener or Visitor). Then show how Closures solve the problem without the creation of extra "helper" objects or unnecessary code frame-working.

You say that your audience is looking for concrete examples of how Closures work. After presenting a few of them, then you can back pedal and properly define a Closure. The technique of presenting the problem, solving it, solving it again, solving it again, and then presenting the greater theory is not foreign to programmers. That's how they discovered patterns in the first place.

划一舟意中人 2024-11-23 06:37:38

我认为为了向 Java 开发人员介绍这个概念,您将闭包与匿名内部类相关联是正确的。我建议解决一些涉及大量使用回调的问题,并展示一张幻灯片,并排比较 Java 中使用匿名内部类所需的代码和 Scala 中使用闭包所需的代码。

以下是涉及回调问题的一些想法:

  1. Swing 按钮单击处理程序
  2. 任何涉及 Runnable 或 Callable(即向 ThreadPoolExecutor 提交任务)
  3. 的内容基于 SAX 事件的 XML 解析
  4. 通过公共事务执行器传递的基于 JDBC 的数据库访问代码减少样板连接获取/释放

对于每个示例,我预计 Scala/闭包解决方案将比 Java/匿名内部类解决方案更短、更简单。

I think you're right on track in relating closures to anonymous inner classes for the sake of introducing the concept to Java developers. I recommend taking some problem that involves heavy use of callbacks, and showing a slide with a side-by-side comparison of the code required in Java using anonymous inner classes and the code required in Scala using closures.

Here are a couple of ideas for problems involving callbacks:

  1. Swing button click handlers
  2. Anything involving a Runnable or Callable (i.e. submitting a task to a ThreadPoolExecutor)
  3. SAX event-based XML parsing
  4. JDBC-based database access code passed through a common transaction executor to cut down on boilerplate connection acquisition/release

For each of these examples, I expect that the Scala/closure solution will turn out shorter and simpler than the Java/anonymous inner class solution.

埖埖迣鎅 2024-11-23 06:37:38

如果您指的是一般的匿名函数,而不仅仅是闭包,我通常使用以下示例。给出一个简单的集合(在本例中是名称列表),并显示使用匿名函数查询和修改是多么简单。

Java - 获取以“A”开头的新名称列表:

List<String> names = Arrays.asList("Ed", "Bob", "Anna");
List<String> namesOnA = new ArrayList<String>();

for(String name : names) {
  if(name.startsWith("A")) {
    namesOnA.add(name);
  }
}

Scala - 获取以“A”开头的名称列表:

val names = List("Ed", "Bob", "Anna")
val namesOnA = names.filter(_.startsWith("A"))

在集合上使用 map、reduceLeft 和其他方法的类似示例。大多数 Java 开发人员都觉得这很有趣。

If you mean anonymous functions in general, and not just closures, I typically use the following example. Give a simple collection (in this case a list of names), and show how much simpler it is to query and modify with anonymous functions.

Java - get a new list of names beginning with "A":

List<String> names = Arrays.asList("Ed", "Bob", "Anna");
List<String> namesOnA = new ArrayList<String>();

for(String name : names) {
  if(name.startsWith("A")) {
    namesOnA.add(name);
  }
}

Scala - get list of names beginning with "A":

val names = List("Ed", "Bob", "Anna")
val namesOnA = names.filter(_.startsWith("A"))

Similar examples using map, reduceLeft and other methods on the collections. Most Java developers find this interesting.

你对谁都笑 2024-11-23 06:37:38

您要求对来自不存在或很少使用闭包的语言的开发人员进行简单的解释。

下面是一个简洁的解释,将它们比作函数返回时不会释放的堆栈帧: "JavaScript 闭包 101- 它们“不是魔法”。我发现这对于苦苦挣扎的传统开发人员来说是一个有用的概念化。

此外,Goslings 在 Java 闭包争论初期对它们的支持也会引起人们的兴趣。给 Java 开发人员。请注意,他还引用了 Neal Gafter 的原始提案,将其包含在爪哇。

You asked for a simple explanation of closures for devs coming from languages where they are non-existent or rarely used.

Here's a succinct explanation likening them to stackframes that are not deallocated when a function returns: "JavaScript Closures 101- they're not magic". I find this to be a helpful conceptualization for a traditional dev struggling with the idea.

Also, Goslings upvote of them in the early days of the Java closure debate would be of interest to Java devs. Note that he also references Neal Gafter's original proposal for their inclusion in Java.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文