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

简介: Ruby和Groovy是两种看上去很相似的编程语言,但由于运行时机制的不同,导致两种编程语言在block中的return语句处理有很大差别。本文解释了这个差异点的具体原因并阐述了在具体编码实践中需要注意的地方。

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的不同行为,并在必要时加以改写。

目录
相关文章
|
IDE Java Linux
2021再拾ruby以及在centos上安装Ruby3.0 vs code运行ruby 狂踩坑记录
2021再拾ruby以及在centos上安装Ruby3.0 vs code运行ruby 狂踩坑记录
228 0
|
IDE Ubuntu Java
|
Ubuntu 关系型数据库 MySQL
【Ruby on Rails全栈课程】1.3 Ruby On Rails运行环境安装 创建并启动项目
一. Ruby On Rails环境安装 1、打开Ubuntu系统(Windows系统打开虚拟机登录到Ubuntu系统;IOS系统在终端打开rails-va文件夹cd rails-va,输入vagrant up,再输入vagrant ssh),更新源列表
162 0