乐趣区

关于groovy:Y-分钟速成-Groovy

源代码下载:learngroovy-cn.groovy

Groovy – Java 平台的动静语言,理解更多。


/*
  装置:1) 装置 GVM - http://gvmtool.net/
  2) 装置 Groovy:gvm install groovy
  3) 启动 groovy 控制台,键入:groovyConsole

*/

//  双斜线开始的是单行正文
/*
像这样的是多行正文
*/

// Hello World
println "Hello world!"

/*
  变量:能够给变量赋值,以便稍后应用
*/

def x = 1
println x

x = new java.util.Date()
println x

x = -3.1499392
println x

x = false
println x

x = "Groovy!"
println x

/*
  汇合和映射
*/

// 创立一个空的列表
def technologies = []

/*** 往列表中减少一个元素 ***/

// 和 Java 一样
technologies.add("Grails")

// 左移增加,返回该列表
technologies << "Groovy"

// 减少多个元素
technologies.addAll(["Gradle","Griffon"])

/*** 从列表中删除元素 ***/

// 和 Java 一样
technologies.remove("Griffon")

// 减号也行
technologies = technologies - 'Grails'

/*** 遍历列表 ***/

// 遍历列表中的元素
technologies.each {println "Technology: $it"}
technologies.eachWithIndex {it, i -> println "$i: $it"}

/*** 查看列表内容 ***/

// 判断列表是否蕴含某元素,返回 boolean
contained = technologies.contains('Groovy')

// 或
contained = 'Groovy' in technologies

// 查看多个元素
technologies.containsAll(['Groovy','Grails'])

/*** 列表排序 ***/

// 排序列表(批改原列表)technologies.sort()

// 要想不批改原列表,能够这样:sortedTechnologies = technologies.sort(false)

/*** 列表操作 ***/

// 替换列表元素
Collections.replaceAll(technologies, 'Gradle', 'gradle')

// 打乱列表
Collections.shuffle(technologies, new Random())

// 清空列表
technologies.clear()

// 创立空的映射
def devMap = [:]

// 增加值
devMap = ['name':'Roberto', 'framework':'Grails', 'language':'Groovy']
devMap.put('lastName','Perez')

// 遍历映射元素
devMap.each {println "$it.key: $it.value"}
devMap.eachWithIndex {it, i -> println "$i: $it"}

// 判断映射是否蕴含某键
assert devMap.containsKey('name')

// 判断映射是否蕴含某值
assert devMap.containsValue('Roberto')

// 获得映射所有的键
println devMap.keySet()

// 获得映射所有的值
println devMap.values()

/*
  Groovy Beans

  GroovyBeans 是 JavaBeans,但应用了更简略的语法

  Groovy 被编译为字节码时,遵循下列规定。* 如果一个名字申明时带有拜访修饰符(public, private, 或者 protected),则会生成一个字段(field)。* 名字申明时没有拜访修饰符,则会生成一个带有 public getter 和 setter 的
      private 字段,即属性(property)。* 如果一个属性申明为 final,则会创立一个 final 的 private 字段,但不会生成 setter。* 能够申明一个属性的同时定义本人的 getter 和 setter。* 能够申明具备雷同名字的属性和字段,该属性会应用该字段。* 如果要定义 private 或 protected 属性,必须提供申明为 private 或 protected 的 getter
      和 setter。* 如果应用显式或隐式的 this(例如 this.foo, 或者 foo)拜访类的在编译时定义的属性,Groovy 会间接拜访对应字段,而不是应用 getter 或者 setter

    * 如果应用显式或隐式的 foo 拜访一个不存在的属性,Groovy 会通过元类(meta class)拜访它,这可能导致运行时谬误。*/

class Foo {
    // 只读属性
    final String name = "Roberto"

    // 只读属性,有 public getter 和 protected setter
    String language
    protected void setLanguage(String language) {this.language = language}

    // 动静类型属性
    def lastName
}

/*
  逻辑分支和循环
*/

//Groovy 反对常见的 if - else 语法
def x = 3

if(x==1) {println "One"} else if(x==2) {println "Two"} else {println "X greater than Two"}

//Groovy 也反对三元运算符
def y = 10
def x = (y > 1) ? "worked" : "failed"
assert x == "worked"

//for 循环
// 应用区间(range)遍历
def x = 0
for (i in 0 .. 30) {x += i}

// 遍历列表
x = 0
for(i in [5,3,2,1] ) {x += i}

// 遍历数组
array = (0..20).toArray()
x = 0
for (i in array) {x += i}

// 遍历映射
def map = ['name':'Roberto', 'framework':'Grails', 'language':'Groovy']
x = ""
for (e in map) {
    x += e.value
    x += " "
}
assert x.equals("Roberto Grails Groovy")

/*
  运算符

  在 Groovy 中以下罕用运算符反对重载:http://www.groovy-lang.org/operators.html#Operator-Overloading

  实用的 groovy 运算符
*/
// 开展(spread)运算符:对聚合对象的所有元素施加操作
def technologies = ['Groovy','Grails','Gradle']
technologies*.toUpperCase() // 相当于 technologies.collect { it?.toUpperCase() }

// 平安导航(safe navigation)运算符:用来防止 NullPointerException
def user = User.get(1)
def username = user?.username


/*
  闭包
  Groovy 闭包好比代码块或者办法指针,它是一段代码定义,能够当前执行。更多信息见:http://www.groovy-lang.org/closures.html
*/
// 例子:def clos = {println "Hello World!"}

println "Executing the Closure:"
clos()

// 传参数给闭包
def sum = {a, b -> println a+b}
sum(2,4)

// 闭包能够援用参数列表以外的变量
def x = 5
def multiplyBy = {num -> num * x}
println multiplyBy(10)

// 只有一个参数的闭包能够省略参数的定义
def clos = {print it}
clos("hi")

/*
  Groovy 能够记忆闭包后果 [1][2][3]
*/
def cl = {a, b ->
    sleep(3000) // 模仿费时操作
    a + b
}

mem = cl.memoize()

def callClosure(a, b) {def start = System.currentTimeMillis()
    mem(a, b)
    println "Inputs(a = $a, b = $b) - took ${System.currentTimeMillis() - start} msecs."
}

callClosure(1, 2)
callClosure(1, 2)
callClosure(2, 3)
callClosure(2, 3)
callClosure(3, 4)
callClosure(3, 4)
callClosure(1, 2)
callClosure(2, 3)
callClosure(3, 4)

/*
  Expando

  Expando 类是一种动静 bean 类,能够给它的实例增加属性和增加闭包作为办法

  http://mrhaki.blogspot.mx/2009/10/groovy-goodness-expando-as-dynamic-bean.html
*/
  def user = new Expando(name:"Roberto")
  assert 'Roberto' == user.name

  user.lastName = 'Pérez'
  assert 'Pérez' == user.lastName

  user.showInfo = { out ->
      out << "Name: $name"
      out << ", Last name: $lastName"
  }

  def sw = new StringWriter()
  println user.showInfo(sw)


/*
  元编程 (MOP)
*/

// 应用 ExpandoMetaClass 减少行为
String.metaClass.testAdd = {println "we added this"}

String x = "test"
x?.testAdd()

// 拦挡办法调用
class Test implements GroovyInterceptable {def sum(Integer x, Integer y) {x + y}

    def invokeMethod(String name, args) {System.out.println "Invoke method $name with args: $args"}
}

def test = new Test()
test?.sum(2,3)
test?.multiply(2,3)

//Groovy 反对 propertyMissing,来解决属性解析尝试
class Foo {def propertyMissing(String name) {name}
}
def f = new Foo()

assertEquals "boo", f.boo

/*
  类型检查和动态编译
  Groovy 天生是并将永远是一门动静语言,但也反对类型检查和动态编译

  更多:http://www.infoq.com/articles/new-groovy-20
*/
// 类型查看
import groovy.transform.TypeChecked

void testMethod() {}

@TypeChecked
void test() {testMeethod()

    def name = "Roberto"

    println naameee

}

// 另一例子
import groovy.transform.TypeChecked

@TypeChecked
Integer test() {
    Integer num = "1"

    Integer[] numbers = [1,2,3,4]

    Date date = numbers[1]

    return "Test"

}

// 动态编译例子
import groovy.transform.CompileStatic

@CompileStatic
int sum(int x, int y) {x + y}

assert sum(2,5) == 7

进阶资源

Groovy 文档

Groovy web console

退出 Groovy 用户组

图书

  • Groovy Goodness
  • Groovy in Action
  • Programming Groovy 2: Dynamic Productivity for the Java Developer
  1. http://roshandawrani.wordpres…
  2. http://www.solutionsiq.com/re…
  3. http://mrhaki.blogspot.mx/201…

有倡议?或者发现什么谬误?在 Github 上开一个 issue,或者发动 pull request!


原文由 Roberto Pérez Alcolea 编写,并由 0 个好心人批改。
Translated by: Todd Gao
© 2022 Roberto Pérez Alcolea
本作品采纳 CC BY-SA 3.0 协定进行许可。

退出移动版