学习Groovy的特性

jopen 9年前

翻译自 http://sysgears.com/articles/groovy-differences-java/

Groovy基于jvm,是一种面向对象的动态语言。如果你需要编写轻量级的脚本并且想要从Java的生态环境中获益,那么Groovy对于你来说是再合适不过的候选者。Groovy动态得被编译成字节码,并且兼容大部分的Java类库。同时Groovy非常易于学习,因为在Groovy中Java的语法都是有效的。但还是有些注意事项需要你在开始编程之前了解的。这篇文章展现了Groovy的一些特性并提供了一些帮助你编写清晰,groovy-style代码的建议。

Groovy beans

声明Groovy beans是非常简单的。典型的Java bean需要包含构造方法,私有属性和getter / setter 方法。Groovy bean仅仅需要field,getter / setter 方法会被隐式得创建。

class User {      String firstName // bean field      String lastName  // bean field  }  def user = new User()  user.firstName = "John"  user.lastName = "Doe"

user.firstName和user.lastName会调用setter方法完成任务。如果有必要的话你也可以为field声明自定义getter / setter 方法。下面举个例子:

class User {        String firstName        String getFirstName() {          "The first name is $firstName"      }        void setFirstName(String firstName) {          this.firstName = "[$firstName]"      }        // ...  }  user.firstName = 'John'  println user.firstName

{}中的内容通过setter方法添加,"the first name"后面通过getter方法得到。结果是这样:

The first name is [John]

如果为field设置了访问修饰符,那就仅仅创建了field,getter / setter方法不会被自动创建。

Groovy 闭包

Groovy提供了一种创建方法为一等对象的方式————Groovy 闭包。使用闭包,你能够定义代码块并且传递参数,就像它是常规变量一样。

// the simplest closure  def hello = {"Hello, $it!"}  assert hello('Chris') == 'Hello, Chris!'    // the closure that do not take any params  def bye = {->'Bye!'}  assert bye() == 'Bye!'    // the closure with several params  def niceHello = {firstName, lastName -> "Hello, $firstName $lastName!"}  assert niceHello('Chris', 'Bennett') == 'Hello, Chris Bennett!'

如上所示,闭包默认持有一个it参数,你可以指定可命名的参数改变这一默认行为。或者声明{-> ...}省略参数。

Groovy list和map

Groovy 为lists和Maps提供了内建的支持,并且允许用类似于JavaScript的方式初始化和操作数据结构。首先,让我们看一眼List的实现,我们可以只用两个[]创建一个空的List。

// an empty list  def emptyList = []    // predefined list  def list = ['One', 'Two', 'Three']

或者从List中取出一个或多个元素。

def list = ['One', 'Two', 'Three']    // gets the first element from the list  assert list[0] == 'One'    // gets a range of elements from the list  assert list[1..2] == ['Two', 'Three']    // gets another range  assert list[-1..-2] == ['Three', 'Two']

另外为迭代和转化lists提供了一系列可用的便捷操作:

// iterates the list  def emptyList = []  list.each {emptyList << "$it!"}  assert emptyList == ['3!', '1!', '2!']    // iterates the list and transforms each entry into a new value  // using the closure  assert list.collect {it * 2} == [6, 2, 4]    // sorts using the closure as a comparator  assert list.sort {it1, it2 -> it1 <=> it2} == [1, 2, 3]    // gets min or max using closure as comparator  assert list.min {it1, it2 -> it1 <=> it2} == 1

Map的实现也有很多的语法糖。可以通过[]和:声明一个空的map:

// an empty map  def emptyMap = [:]    // predefined map  def map = [John: 10, Mark: 20, Peter: 'Not defined']

两种风格获取Map的值————bean风格或者数组风格

def map = [John: 10, Mark: 20, Peter: 'Not defined']    // the array style  assert map['Peter'] == 'Not defined'    // the bean style  assert map.Mark == 20    // also you can preset default value that will be returned by  // the get method if key does not exist  assert map.get('Michael', 100) == 100

借助闭包实现迭代和转换:

// iterates the map  def emptyMap = [:]  def map = [John: 10, Mark: 20, Peter: 'Not defined']  map.each { key, value ->      emptyMap.put key, "$key: $value" as String  }  assert emptyMap == [John: 'John: 10', Mark: 'Mark: 20',           Peter: 'Peter: Not defined']    // iterates the map and transforms each entry using  // the closure, returns a list of transformed values  assert map.collect { key, value ->      "$key: $value"  } == ['John: 10', 'Mark: 20', 'Peter: Not defined']    // sorts map elements using the closure as a comparator  map.put 'Chris', 15  assert map.sort { e1, e2 ->      e1.key <=> e2.key  } == [John: 10, Chris: 15, Mark: 20, Peter: 'Not defined']

其他有用的

  • boolean操作符==和Java中的equals相同效果,并且不区分类型。不像Java中==意味着基本类型相等和对象地址相等。如果你要比较对象的地址,使用is方法:

    assert [] == []     assert ![].is([])
  • .*操作符被引入用于表示在集合内所有的成员上执行操作:

    assert [1, 2, 3] == ['a', 'ab', 'abc']*.size()
  • 在方法的末端return是可选的:

    def foo() {         // do something         return something     }     // is equals to     def bar() {         // do something         something     }

结语

Groovy还有很多有趣的特性:元编程,函数式编程,AST转换。在学习的路途上你一定会发现它们。Groovy的强大之处在于,你可以用基本的Java语法开始,然后逐步学习并且改进代码直到它们真正意义上的灵活和动态。