文章导读:在新的一年中,各位网友都进入紧张的学习或是工作阶段。网学的各位小编整理了JAVA-Java中闭包特性受质疑:for循环为何可恨?的相关内容供大家参考,祝大家在新的一年里工作和学习顺利!
Java的闭包(Closure)特征最近成为了一个热门话题。一些精英正在起草一份议案,要在Java将来的版本中加入闭包特征。然而,提议中的闭包语法以及语言上的这种扩充受到了众多Java程序员的猛烈抨击。 不久前,出版过数十本编程书籍的大作家Elliotte Rusty Harold发表了对Java中闭包的价值的质疑。尤其是他问道“ for 循环为何可恨?”: 我不知道,有些人这么着急的要把 for 循环消灭掉,他们反对的究竟是什么?这已经不是第一次或第二次计算机学界的理论家们起来反对 for 循环(或类似的东西)了。 如果只说Elliotte质疑不起眼的闭包的价值,这是不公平的。他主要抱怨是,在读了另一位著名人物、获得过Jolt 大奖并创造过最高销售记录的《Better, Faster, Lighter Java》的作者Bruce Tate的最近的关于此主题的专题后,他看不出闭包在Java中有什么价值。(Bruce用Ruby做的例证): 表 1. 最简单的闭包 3.times {puts "Inside the times method."} 结果: Inside the times method. Inside the times method. Inside the times method. times是3这个对象上的一个方法。它把闭包中的代码执行了3次。{puts "Inside the times method."}是闭包。它是一个匿名函数,把它传入times方法,打印出静态句子。相比起传统的for循环语句,这样的代码显得更紧凑,更简单,如表2中所示: 表 2: 非闭包的循环 for i in 1..3 puts "Inside the times method." end 由于这种毫无生气的对闭包的介绍,我也很难看出它的真正价值。这首个比较,充其量也就能体现出一种微妙的差别。Bruce在developerWorks上的文章里的其它的例子也大多是价值不大的,要么含糊不清,要么缺乏启发意义。 对于这种Ruby风格的闭包给Elliotte带来的困惑,我不打算进一步评论;对这种问题过于挑剔毫无意义。我也不想讨论目前的关于Java中的 闭包的语法的提议的争论,包括Java中是否应该有闭包这样的大问题。在这样的争论中我没有立场,说实话,我是不在乎这些问题如何或何时被解决。 虽然如此,Elliotte却提出了一个重要的问题:for 循环为什么可恨? 下面是一个常见的例子: double sum = 0; for (int i = 0; i < array.length; i++) { sum += array[i]; } 这有什么问题?我编了很多年的程序,我对这种语法一眼扫过去很舒服;很显然,它是把一个数组里的值加到一起。但当去真正的阅读这段代码时,这四行代码里大概散布着30多个标记符号需要我去分析处理。不错,有些字符可以通过语法简写方式来缩减。但为了这样一个简单的加法,你需要写出一堆东西,还要保证写的正确。 凭什么这样说?下面是Elliotte的文章里另外一个例子,原文拷贝: String s = ""; for (int i = 0; i < args.length; i++) { s += array[i]; } 看见了里面的错误吗?如果这代码编译通过,并通过的代码审查,你可能需要数周才会发现这样的bug,再数周才能制作出补丁。这些只是简单的for循 环。想象一下,当for循环体变得越来越大,甚至有嵌套时,事情会变得多么的复杂。(如果你仍旧不担心这样的bug,认为这只是拼写错误,那么你就想想有 多少次在for循环里你是这样的。) 如果你能够把一个简单的for循环写成一行,带有更少的重复和更少的字符,这样不仅更容易阅读,也更容易书写。因为这样更简洁,引入bug的机会就更少,当bug出现时,也更容易被发现。 那闭包对此有何帮助?下面是第一个例子,用Haskell语言写成的: total = sum array 哈哈,我是在说谎。sum函数并没有使用闭包。它是按照fold的方式定义的,而fold是接受闭包的: 下面是第