Ruby和Groovy的一个运行时差异点

Ruby和Groovy是两种看上去很相似的编程语言,但由于运行时机制的不同,导致两种编程语言在block中的return语句处理有很大差别,具体原因在于:

  • Ruby在语言设计上很大程度上参考了Smalltalk。在Smalltalk编程语言中,block可以直接返回到调用函数外层,这一语言特性称为non-local return。Ruby也有此特性。
  • Groovy的运行时是基于JVM的,在JVM规范中不存在non-local return这样的特性,于是,在block中使用return语句的行为就和Ruby不同。

在下面这段Ruby代码中,由于non-local return特性,bar函数里的block中的return语句会导致bar函数返回:

def foo
    [1,2,3].map{ |a| 2*a }
end

def bar
    [1,2,3].map{ |a| return 2*a }
end

p foo #[2, 4, 6]
p bar #2

同样的Groovy代码,在block中使用return语句不会对运行结果产生影响, foo和bar这两个函数的行为完全一样:

def foo() {
    [1, 2, 3].collect { it * 2 }
}

def bar() {
    [1, 2, 3].collect { return it * 2 }
}

println(foo()) //[2, 4, 6]
println(bar()) //[2, 4, 6]

再看一个更真实的例子:

Ruby代码实现的一个判重逻辑:

def in_list(l, e)
    l.each do |x|
        if x == e then
            return true
        end
    end
    return false
end

p in_list([1, 2], 1) #true

同样写法的Groovy代码的运行结果是不对的:

def in_list(l, e) {
    l.each {
        if (it == e) {
            return true
        }
    }
    return false
}

println(in_list([1, 2], 1)) #false

必须改写成:

def in_list(l, e) {
    for (it in l) {
        if (it == e) {
            return true
        }
    }
    return false
}

println(in_list([1, 2], 1)) #true

综上,当同时使用这两种编程编程语言编码时必须加倍小心,特别要注意分辨带return语句的block的不同行为,并在必要时加以改写。

上一篇:Eclipse中如何恢复已删除文件


下一篇:Android--百度地图开发(二)