当前位置: 网学 > 编程文档 > JAVA > 正文

Java中闭包特性受质疑:for循环为何可恨?

来源:Http://myeducs.cn 联系QQ:点击这里给我发消息 作者: 用户投稿 来源: 网络 发布时间: 13/08/04
二个例子,很常见,而且使用了闭包:  s = concat array  s = foldr (++) [] array  我承认,使用这些叫做foldl 和 foldr 样子古怪的函数来解释闭包的作用,这对那些更熟悉for循环的程序员来说没有多大意义。但是,这几个函数却能突出for循环的关键弊端:它把三种独立不同的操作合并到一起了——过滤,归纳和转换。  上面的这两种for循环,它们的目标是接收一个数值列表,把它们归纳成一个值。函数式编程的程序员称这些操作为“folds(合并)”。一个 fold运算的过程是,首先要有一个操作(一个闭包)和一个种子值,还有使用list里的第一个元素。这个操作被施加到种子值和list里的第一个元素 上,产生出一个新的种子值。fold运算然后把这个操作运用到新种子值和list里的下一个元素上,一直这样,直到最后一个值,最后一次操作的结果成为 fold运算的结果。  下面是一个演示:  s = foldl (+) 0 [1, 2, 3]  = foldl (+) (0 + 1) [2, 3]  = foldl (+) 1 [2, 3]  = foldl (+) (1 + 2)   = foldl (+) 3   = foldl (+) (3 + 3) []  = foldl (+) 6 []  = 6  Haskell语言里提供了很多fold函数;foldl函数从list的第一位开始运算,依次反复到最后一个,而foldr函数,它从list的最后一个函数开始运算,从后往前。还有很多其它相似的函数,但这两个是最基本的。  当然,folds是一些非常基本的运算,如果抛弃for循环而以各种形式的foldl 和 foldr 咒符来替换,你会很困惑。事实上,更高级的操作,例如sum, prod 和 concat都是以各种folds定义的。当你的代码以这种高级的归纳操作运算来编写时,代码会变得更简洁,更易读,更易写,更易懂。  当然,并不是所有的for循环都是归纳操作。看看下面这个:  for (int i = 0; i < array.length; i++) {  array[i] *= 2;  }  这是一个转换操作,函数式编程的程序员称之为map操作:  new_array = map (*2) array  map函数的工作方式是,它会检查list里的每个元素,将一个函数应用到每个元素上,形成一个新的list,里面是新的元素。(有些语言里的这种操作是原位替换)。这是一个很容易理解的操作。sort函数的功能相似,它接受一个list,返回(或修改)一个list。  第三种类型的for循环是过滤。下面是个例子。  int tmp[] = new int[nums.length];  int j = 0;  for (int i = 0; i < nums.length; i++) {  if ((nums[i] % 2) == 1) {  tmp[j] = nums[i];  j++;  }  }  这是一个非常简单的操作,但使用了for循环和两个独立的计数器后,毫无必要的复杂表现把事实真相完全掩盖了。如果过滤是一种基本的操作,它应该像一个fold或一个map那样,而事实上,它是的:  odds = filter (i => (i `mod` 2) == 1) nums  odds = filter isOdd nums -- 更常用的形式  从核心上讲,这就是为什么for循环有问题:它把(至少)三种独立的操作合并到了一起,但重点却关注了一个次要细节问题:遍历一系列的值。而事实上,fold,map 和 filter是处理一个数据list的三种不同的操作,它们应该被分别处理。采用把闭包传入循环内的方式,我们能更容易的把what 从 how 中分离出来。每次遍历一个list时我都会使用一个匿名函数,或复用通用的函数(例如 isOdd, (+) 或 sqrt)。  虽然闭包并不是一个很深奥的概念,但当它深深的烙进了一种语言和它的标准库中时,我们不需要使用这些低级的操作搞的代码混乱不堪。相反,我们可以创建更高级的运算,做我们想要的事,比如sum andprod。  更重要的,以这些概念思考问题会使我们更容易思考更复杂的操作,比如变换一个tree,过滤一个vector,或把一个list合并成一个hash。  在最后,Elliotte

网学推荐

免费论文

原创论文

浏览:
设为首页 | 加入收藏 | 论文首页 | 论文专题 | 设计下载 | 网学软件 | 论文模板 | 论文资源 | 程序设计 | 关于网学 | 站内搜索 | 网学留言 | 友情链接 | 资料中心
版权所有 QQ:3710167 邮箱:3710167@qq.com 网学网 [Myeducs.cn] 您电脑的分辨率是 像素
Copyright 2008-2015 myeducs.Cn www.myeducs.Cn All Rights Reserved
湘ICP备09003080号