groovy开始使用groovy


备注

Groovy是

  • 是Java虚拟机的可选类型动态语言

  • 基于Java的优势,但具有受Python,Ruby和Smalltalk等语言启发的额外功能特性

  • 使Java开发人员可以使用现代编程功能,学习曲线几乎为零

  • 提供静态类型检查和静态编译代码的能力,以获得稳健性和性能

  • 支持特定于域的语言和其他紧凑的语法,因此您的代码易于阅读和维护

  • 通过其强大的处理原语,OO功能和Ant DSL,使编写shell和构建脚本变得容易

  • 通过在开发Web,GUI,数据库或控制台应用程序时减少脚手架代码来提高开发人员的工作效率

  • 通过支持单元测试和开箱即用的模拟简化测试

  • 与所有现有Java类和库无缝集成

  • 直接编译为Java字节码,因此您可以在任何使用Java的地方使用它

版本

你好,世界

Hello World的Groovy版本。

println 'Hello World!'
 

你好世界在groovy

下面的例子说明使用脚本在groovy中最简单的Hello World ,将以下代码片段放在一个文件中,比如helloWorld.groovy

println 'Hello World!'
 

如何执行:在命令行中, groovy helloWorld.groovy

输出: Hello World!

你好世界Shebang(linux)

给出一个包含内容的hello.groovy文件:

#!/usr/bin/env groovy
println "Hello world"
 

如果给定执行权限,则可以从命令行执行

$ ./hello.groovy
 

安装或设置

安装Groovy有两种常用方法。

下载

Groovy二进制文件可以在Groovy网站的下载页面上下载 。您可以解压缩归档并将%GROOVY_HOME%/bin/groovy.bat 的路径%GROOVY_HOME%/bin/groovy.bat 到PATH系统环境变量,其中%GROOVY_HOME%是解压缩Groovy的目录。

SDKMAN

另一种选择是使用SDKMAN 。这个选项迅速普及,使得管理Groovy的多个版本变得非常简单。它还支持“GR8”生态圈中的其他应用。此选项在Linux和Mac上本机运行良好,但在Windows上需要Cygwin

按照Groovy下载页面上的说明,您可以执行以下步骤来安装SDKMAN。

$ curl -s get.sdkman.io | bash

安装SDKMAN后,您现在可以访问sdk 命令。使用此命令,您可以执行许多有用的操作。

安装Groovy

$ sdk install groovy

这将安装最新版本的Groovy。

列出Groovy的版本

$ sdk ls groovy

这允许您在Groovy软件上运行Linux样式ls 命令,列出所有可用选项。每个安装的版本旁边都有一个* ,并且> 表示您当前的版本。

切换Groovy的版本

$ sdk use groovy 2.4.7

这会将当前版本的Groovy更改为2.4.7。如果您安装了其他版本,则可以切换到其中任何一个版本。

您可以使用groovy -version 命令列出当前版本的groovy。

豪华-GVM

SDKMAN的初始名称是GVM, posh-gvm是Windows Powershell的GVM端口。因此,如果您在Windows机器上开发并且不想在Cygwin上使用SDKMAN,则posh-gvm适合您。它与SDKMAN的工作方式相同,但命令是gmv ,而不是sdk 。所以

PS C:\Users\You> gmv install groovy
 

将在您的Windows机器上通过posh-gvm安装groovy。

在Java项目上使用Groovy

Groovy可以访问所有java类,实际上Groovy类是Java类,可以直接由JVM运行。如果您正在开发Java项目,那么使用Groovy作为一种简单的脚本语言来与您的Java代码进行交互是一件很容易的事情。

为了使事情变得更好,几乎任何Java类都可以重命名为.groovy并编译和运行,并且将完全像它一样工作,groovy接近于Java的超集,这是groovy的既定目标。

Groovy有一个REPL。 groovysh 附带了Groovy,如果你的类路径设置正确,可以用来快速实例化和测试Java类。例如,如果您的classpath 指向您的eclipse“classes / bin”目录,那么您可以将文件保存在eclipse中,跳转到groovysh 并实例化该类以测试它。

使用Groovy而不仅仅是Java的原因是:类加载器在编译时拾取新类很有用。在开发时,通常不需要退出/重新启动groovysh

语法是TERSE。这对于可维护的代码来说并不是很好,但对于脚本和测试,它可以显着减少代码。它所做的一件大事就是消除已检查的异常(或者更准确地说,将所有已检查的异常转换为未经检查的异常)。这会像这样打开代码(一秒后打印你好):

class JavaClass {
    public static void main(String[] args) {
        try {
            Thread.sleep(1000);
        } catch(InterruptedException e) {
            // You shouldn't leave an empty catch block, but who cares if this was interrupted???
        }
        System.out.println("Hello!");
    }
}
 

进入Groovy的:

Thread.sleep(1000)
print "Hello!"
 

Groovy也有非常紧凑的初始化语法。这允许您根据需要指定数据而无需考虑它:

在Java中初始化地图你应该做这样的事情:

String[] init = { "1:Bill", "2:Doug", "3:Bev" };
// Note the rest of this can be put in a function and reused or maybe found in a library, but I always seem to have to write this function!
Map m = new HashMap<Integer, String>();
for(String pair : int) {
    String[] split = pair.split(":");
    m.put(new Integer(split[0]), split[1])
}
 

这还不错,但还需要维护。在groovy你只会使用:

Map map = { 1 : "Bill", 2 : "Doug", 3 : "Bev" }
 

你完成了。列表语法同样简单。

另一个非常大的优势是groovy的闭包语法。它非常简洁有趣,维护起来有点困难,但对于不是优先考虑的脚本。举个例子,这里有一些groovy代码,用于查找当前目录中包含单词Hello 所有.txt 文件:

println new File('.').files.findAll{ it.name.endsWith('.txt') && it.text.contains('Hello') }.collect{ it.name }
 

这个例子使用了一些“Groovy”技巧:

  • .files 引用getFiles() 方法 - groovy可以随意在getter / setter和属性语法之间切换

  • it. 指的是迭代的当前元素。 { it }{ it -> it } 的快捷方式,例如:

    [1,2,3] .collect {it ^ 2} == [1,4,9]

  • it.textit 是一个文件)使用一个方法groovy添加到File 来检索File 的整个文本。这在脚本中非常有用。

在列表上使用inject()创建CSV字符串

在Groovy中,inject()方法是允许我们向实现inject()方法的任何对象添加(或注入)新功能的累积方法之一。对于Collection,我们可以统一对一组对象应用闭包,然后将结果整理为单个值。 inject()方法的第一个参数是累积的初始值,第二个参数是闭包。

在此示例中,我们将字符串列表作为参数,并输出由逗号分隔的字符串的值。我已经使用此功能将值列表附加到REST查询字符串,如果稍微修改它,我已经使用它将值包含到SQL语句中作为IN子句的一部分。这是执行此操作的代码:

public String convertToCSV( List<String> list ) {
    if (list == null) {
        return ""
    }
    return list.inject( '' ) { result, item ->
        result + ( result && item ? ',' : '' ) + ( item ? "${item.trim()}" : '' )
    }
}

assert convertToCSV( null ) == ""
assert convertToCSV( ["aaa", "bbb  ", null, "  ccc  "] ) == "aaa,bbb,ccc" 
 

在此示例中,inject()方法的第一个参数是零长度字符串,这意味着在处理列表的第一个元素时,结果也是零长度字符串。这在第一个三元评估中解析为false,这就是我们在字符串开头没有逗号的原因。每次连续迭代遍历列表的元素,结果将成为自身的连接,逗号,然后是下一个项目,直到我们到达列表中的最后一项。

这种方法的优点是您不需要循环结构之外的变量来保存连接的String结果。这意味着这可能会导致代码中出现副作用。使用inject()方法,会注入此行为,并且集合会为您调整对闭包的调用结果。这种方法的缺点是可读性。但是通过一些经验,它变得更容易阅读和理解,我希望这个例子可以帮助您实现这一目标。