论坛首页 编程语言技术论坛

迭代器+代码块,让代码更简短

浏览 8304 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
作者 正文
   发表时间:2007-02-18  

        刚开始接触ruby,作为一个以JAVA开发为主的程序员,ruby的代码风格多少让我有点不太适应,也许习惯了复杂的风格,再简单起来就比较困难了吧, 看来没有其他语言牵绊的话,学起ruby应该更快。

        今天看了下ruby中的迭代器和代码块,这两个概念在其他语言当中也有,但是ruby中的迭代器和代码块却给我焕然一新的感觉,也让我更加了解到ruby代码简短的一个原因,正所谓实践出真知,就让我举个简单的例子吧:

        一个包含一个存储字符串的数组的类,写一个[]方法,方法传递一个key参数,如果参数为整数则直接用索引返回字符串,如果不是整数则判断数组中是否存在该值,存在则返回该字符串,否则返回nil。以下只写[]方法的实现

        按照一般的写法

         def [](key)
           if key.kind_of?(Integer)
             return @arr[key]
           else
            for i in 0...@arr.length
               return @arr[i] if key == @arr[i]
            end
          end
          return nil
         end

       这种写法我想大多数刚刚接触ruby的朋友都应该很熟悉,在其他语言中一般也是类似的写法,现在我们使用代码块+迭代器对这段代码改写一下

         def [](key)
           if key.kind_of?(Integer)
             result = @arr[key]
           else            
               result = @arr.find{|str| key == str}            
          end
          return result
         end

        是不是简短了很多呢?主要就是@arr.find{|str| key == str} 这一句代码,find方法是Array的一个迭代器,而后面大括号中的内容就是一段代码块,这样就实现了和最上面那段代码一样的功能,且代码也简短了不少,让我们一起来看看find方法的大概实现吧

        def find  
            for i in 0...size  
                value = self[i]  
                return value if yield(value)  #此处调用代码块中的代码
            end  
            return nil  
        end  

        value if yield(value)  这一句的yield就是调用代码块中的代码,后面括号的内容就是代码块的参数, 看到这里,相信不少刚刚接触的ruby的朋友都可能会觉得满意了,不,其实这段代码还能更简单,请看

        def [](key)  
           return @arr[key] if key.kind_of?(Integer)      
           return @arr.find { |str| str == key }
        end

        哇,是不是又让人吃了一惊呢?居然仅仅两行代码就OK了,是否很惊奇呢?我也一样很惊奇,在没接触ruby之前,就到处听人说ruby的神奇之处,写ruby代码是一种享受,开始却是很怀疑,等到自己真正接触之后,才发现写ruby程序真的是一种享受,也许一开始无法一下能把代码写到最简单,而且也很难习惯ruby的风格,不过没有关系,只要有心,就一定能写得好,习惯是慢慢养成的。本文参考了Programming Ruby中的例子,有条件的朋友可以去买本来看看,这本书却是是ruby入门的好教材。

   发表时间:2007-02-18  
对于你的这一个特定问题,看过SICP第二章之后你就不会自己写循环去做数组过滤。
0 请登录后投票
   发表时间:2007-02-18  
呵呵,我水平有限,SICP也没看过,多谢gigix的建议,我一定会找本来看看
0 请登录后投票
   发表时间:2007-02-18  
简单地说,列表(LISP黑话,也就是数组)有几个基本操作,用Ruby的黑话来说就是map, inject和find(以及衍生出来的reject)。一般而言几乎所有的循环遍历数组操作都可以归约为基本操作或者基本操作的组合。这样做的好处之一是你不必一遍又一遍地写循环代码,更重要的好处是清晰地描述你做遍历操作的目的
0 请登录后投票
   发表时间:2007-02-19  
   明白,在实际编写过程中当然不会一遍又一遍的写循环代码,我之所以写这篇文章只是想展示一下ruby的简单性和直观性,不可否认,很多初初接触ruby的朋友,不可能一开始就能将这段代码写得如此简单。
    对SICP下了订单,听说这本书有点难度,以后有不明白的地方请gigix多多指点。
0 请登录后投票
   发表时间:2007-02-19  
gigix继续看,特别是第四章,你会发现列表还是有不同于数组的地方的。
0 请登录后投票
   发表时间:2007-02-19  
calmness 写道
   明白,在实际编写过程中当然不会一遍又一遍的写循环代码,我之所以写这篇文章只是想展示一下ruby的简单性和直观性,不可否认,很多初初接触ruby的朋友,不可能一开始就能将这段代码写得如此简单。
    对SICP下了订单,听说这本书有点难度,以后有不明白的地方请gigix多多指点。

实际上用Java编程你就会这样做。关键在于用Java的时候即便你想采用函数式的列表操作,动用匿名函数写出来的代码量一点都不比直接写循环来得少,可读性反而更低(ajoo以前有个帖子讲这事),其结果是习惯了Java的程序员可能压根就不想用列表操作。
0 请登录后投票
   发表时间:2007-02-19  
关于实际JAVA开发中我会如何做在此不多做讨论,而我所说的:“在实际编写过程中当然不会一遍又一遍的写循环代码”是指ruby而言,请gigix不要误会,呵呵
0 请登录后投票
论坛首页 编程语言技术版

跳转论坛:
Global site tag (gtag.js) - Google Analytics