Groovy基础语法

动态类型

Groovy定义变量时:可以用Groovy风格的def声明,不指定类型;也可以兼容Java风格,指定变量类型;甚至还可以省略def或类型

def t1 = 't1'
String t2 = 't2'
t3 = 't3'

Groovy风格定义的变量类型是动态的,编译成class时会自动转换成正确的Java类型

def var = 'text'
println var
var = 5
println var + 1

可用Java实现类似效果如下

Object o = "text";
System.out.println(String.valueOf(o));
o = 5;
System.out.println(String.valueOf(Integer.valueOf(o) + 1));

字符串

Groovy支持灵活的字符串语法,例如:

// 单引号字符串
def a = 'hello "world"' // 双引号字符串
def b = "What's the weather like?" // 用加号连接字符串,用等号对比字符串
assert 'ab' == 'a' + 'b' // 三个单引号字符串,支持直接换行
def aMultilineString = '''line one
line two
line three''' // 斜线字符串中,反斜线不需要转义,常用于正则表达式
def fooPattern = /.*foo.*/ // 双引号字符串支持用$嵌入变量
def name = 'Tom'
def greeting = "Hello ${name}" // 如需函数调用,则$后表达式要加大括号
def pi = 3.14
def piString = "Pi = ${pi.toString()}"

闭包 (Closure)

  • 闭包是一个变量,又是一个函数,类似C语言中的函数指针,或者Java中只有一个方法的接口(Runnable等)
  • 反编译class文件可以看出,Groovy闭包都会转化为继承groovy.lang.Closure的类
  • 闭包方法的参数用箭头定义,如果不特殊指定,则默认有一个it参数
  • 闭包方法的返回值可以用return显示指定,如果不指定则使用最后一条语句的值
def c1 = {
println 'hello'
}
def c2 = { a, b ->
println a
println b
}
def c3 = { int a, String b ->
println a
println b
}
def c4 = { ->
println 'hello'
}
def c5 = {
println it
}
def c6 = {
return it + 1
}
def c7 = {
it + 1
}

闭包调用可以用call,也可以直接像Java方法一样加括号调用。

def c = {
println it
}
c.call('text1')
c('text2')

Java实现闭包效果:

abstract class MyClosure {
abstract void call(Object o);
}
MyClosure c = new MyClosure() {
@Override
void call(Object o) {
System.out.println(String.valueOf(o));
}
};
c.call("text");

方法/闭包的定义与调用

Groovy中定义方法既可以用Groovy闭包风格,也可以用Java风格,参数/返回值类型也是可选的

def f1 = { text ->
println text
}
def f2(text) {
println text
}
void f3(String text) {
println text
}

注意函数定义不能这么写,会被视为函数调用

f4(text) {
println text
}

调用带参数的闭包/函数,通常可以省略括号,如果最后一个参数是闭包,还可以单独写在括号后面,如下:

println('hello')
println 'hello' def func = { text, Closure closure ->
println text
closure.call()
} func('1', {
println '2'
})
func '3', {
println '4'
}
func('5') {
println '6'
}

delegate,owner,this

查看Closure类的源码,可以发现闭包中有delegate、owner、this三个成员变量,调用闭包没有的属性/方法时,会尝试在这三个变量上调用。一般情况下:

this指向闭包外部的Object,指定义闭包的类。

owner指向闭包外部的Object/Closure,指直接包含闭包的类或闭包。

delegate默认和owner一致,指用于处理闭包属性/方法调用的第三方对象,可以修改。

在闭包构造时this和owner就已经确定并传入,是只读的。如果需要修改,可以用Closure.rehydrate()方法克隆新的闭包,同时设置其this和owner。

Closure还有一个resolveStrategy属性,有多种值(OWNER_FIRST、DELEGATE_FIRST、OWNER_ONLY、DELEGATE_ONLY、TO_SELF),默认为OWNER_FIRST,表示调用闭包没有定义的属性/方法时,先尝试从owner取,再尝试从delegate取。

Groovy代码示例:

class MyDelegate {
def func = {
println('hello')
}
}
def c = {
func()
}
c.delegate = new MyDelegate()
c.call()

用Java实现类似效果如下:

static boolean callMethod(Object o, String method, Object... args) {
try {
Method func = o.getClass().getDeclaredMethod(method);
if (func != null) {
func.invoke(o, args);
return true;
}
} catch (Exception ignored) {
}
return false;
}
class MyDelegate {
void func() {
System.out.println("func");
}
}
abstract class MyClosure {
Object delegate;
abstract void call();
}
MyClosure c = new MyClosure() {
@Override
void call() {
if (!callMethod(this, "func")) {
callMethod(delegate, "func");
}
}
};
c.delegate = new MyDelegate();
c.call();

属性与Getter、Setter

Groovy中对象的属性(通常即成员变量)可以直接用名字访问,实际上会调用getter和setter

// File没有absolutePath的成员变量,但有getAbsolutePath方法,可以直接当属性访问
println new File('text').absolutePath

// File没有setAbsolutePath方法,这句会报ReadOnlyPropertyException
new File('text').absolutePath = '1'

Groovy系列(3)- Groovy基础语法的更多相关文章

  1. php从入门到放弃系列-02.php基础语法

    php从入门到放弃系列-02.php基础语法 一.学习语法,从hello world开始 PHP(全称:PHP:Hypertext Preprocessor,即"PHP:超文本预处理器&qu ...

  2. [Swift2.0系列]Defer/Guard 基础语法

    1.Defer Swift2.0中加入了defer新语法声明.defer译为延缓.推迟之意.那么在Swift2.0中它将被应用于什么位置呢?比如,读取某目录下的文件内容并处理数据,你需要首先定位到文件 ...

  3. MYSQL从入门到放弃系列:mysql基础语法

    Mysql基本语法 启动MySQL net start mysql 连接与断开服务器 mysql -h 地址 -P 端口 -u 用户名 -p 密码 跳过权限验证登录MySQL mysqld --ski ...

  4. Gradle Groovy 基础语法 MD

    Markdown版本笔记 我的GitHub首页 我的博客 我的微信 我的邮箱 MyAndroidBlogs baiqiantao baiqiantao bqt20094 baiqiantao@sina ...

  5. Gradle系列之一 Groovy语法精讲

    Gradle技术之一 Groovy语法精讲 gradle脚本是基于groovy语言开发的,想要学好gradle必须先要对groovy有一个基本的认识 1. Groovy特点 groovy是一种DSL语 ...

  6. Groovy基础语法

    Groovy 基础语法 变量定义 1.支持动态类型,使用def关键字定义变量 // Java中定义变量的方式 int age = 18; String name = "张三"; / ...

  7. Groovy系列-groovy比起Java--有哪些地方写起来更舒服?

    groovy比起java-有哪些地方写起来更舒服 java发展缓慢,语法落后冗余 说起java,其实java挺好的,java现在的性能也不错,但是,java的语法显然比较落后,而且冗余,getter/ ...

  8. emmet 系列(1)基础语法

    emmet 系列(1)基础语法 emmet 是一个能显著提升开发html和css开发效率的web开发者工具 emmet基本上目前已知的编辑器都有相应的插件,各个编辑器的emmet插件的下载地址:点我下 ...

  9. openresty开发系列15--lua基础语法4表table和运算符

    openresty开发系列15--lua基础语法4表table和运算符 lua中的表table 一)table (表)Table 类型实现了一种抽象的"关联数组".即可用作数组,也 ...

随机推荐

  1. Redis应用场景及缓存问题

    1.应用场景 (1)   缓存 缓存机制几乎在所有的大型网站都有使用,合理地使用缓存不仅可以加快数据的访问速度,而且能够有效地降低后端数据源的压力.Redis 提供了键值过期时间设置,并且也提供了灵活 ...

  2. NOIP 模拟 $31\; \rm Cover$

    题解 \(by\;zj\varphi\) 因为对于所有区间,都只有包含和被包含关系,这就是一个树形结构. 设 \(\rm f_{i,j}\) 表示在第 \(\rm i\) 个节点,最多被覆盖 \(\r ...

  3. C# wpf中关于binding的converter无效的情况

    最近碰到bingding设置了convert转换无效的问题.困扰了我好久.这里记录分析一下. 先说下现象 我把TextBox的text属性  绑定到了对应的 convert.代码如下 希望吧pd_no ...

  4. [SWMM]出现问题及解决

    1,节点顺序 [错误]:如下图,在SWMM软件中普通节点到出水口的连接线不能正常连接,提示找不到出水口节点,但在inp文件中是存在的! [解决]:需要先写入点节点再写入线节点,即先写入[JUNCTIO ...

  5. 刷题-力扣-LCP 07. 传递信息

    LCP 07. 传递信息 题目链接 来源:力扣(LeetCode) 链接:https://leetcode-cn.com/problems/chuan-di-xin-xi 著作权归领扣网络所有.商业转 ...

  6. WSL(Ubuntu)下安装Redis

    一.安装 输入命令安装redis-server sudo apt-get install redis-server 安装完成后打开redis.conf文件,找到bind 127.0.0.1,更改为bi ...

  7. JS方式实现隐藏手机号码中间4位数

    1.截取 function test (value) { const start = value.slice(0, 3) const end = value.slice(-4) return `${s ...

  8. 关于通用Mapper new Example使用记录

    关于通用MapperExample使用记录 环境准备 需要集成 mybatis 的 generator 插件,方便自动生成 实体类和 mapper 类,还可以生成xml,不过一般我们都不用 xml b ...

  9. ubuntu软件工具推荐

    时间:2019-04-11 记录:PangYuaner 标题:串口调试利器--Minicom配置及使用详解 地址:https://www.cnblogs.com/wonux/p/5897127.htm ...

  10. C#多线程开发-线程基础 01

    最近由于工作的需要,一直在使用C#的多线程进行开发,其中也遇到了很多问题,但也都解决了.后来发觉自己对于线程的知识和运用不是很熟悉,所以将利用几篇文章来系统性的学习汇总下C#中的多线程开发. 线程基础 ...