Groovy 语法-表达式知识学习

开发 前端
本篇主要介绍了一下Groovy的表达式的定义和GPath表达式的简单定义。其中GPath是java中没有的写法。可以支持多级对象结构,也可以用于Json,XMl的解析中来。

1. 介绍

本篇内容为Groovy学习笔记第31篇。继续学习语法相关的知识点。本篇的重点是Expressions(表达式)的相关知识点。

表达式是Groovy程序的构建块,用于引用现有值并执行代码以创建新值。

2. 表达式

Groovy支持许多与Java相同的表达式,如下:

表达式示例

描述

​foo​

变量、字段、参数的名称…

​this​​​, ​​super​​​, ​​it​

特殊名字

​true​​​, ​​10​​​, ​​"bar"​

​String.class​

类名称值

​(​​ expression ​​)​

带括号的表达式

​foo++​​​, ​​~bar​

一元运算符表达式

​foo + bar​​​, ​​bar * baz​

二进制运算符表达式

​foo ? bar : baz​

三元运算符表达式

​(Integer x, Integer y) → x + y​

Lambda表达式

​assert 'bar' == switch('foo') { case 'foo' -> 'bar' }​

switch表达式

上面的表达式形式是java也支持的表达式。而Groovy也有一些自己独有的表达式:

表达式示例

描述

​String​

缩写类文字(当不明确时)

​{ x, y → x + y }​

闭包表达式

​[1, 3, 5]​

文字列表(List)表达式

​[a:2, b:4, c:6]​

文字映射(Map)表达式

Groovy还扩展了Java中用于成员访问的普通点表示法。Groovy通过指定某些感兴趣数据的层次结构中的路径,为访问分层数据结构提供了特殊支持。这些Groovy路径表达式称为GPath表达式。

2.1 GPath 表达式

GPath​是一种集成到Groovy中的路径表达式语言,它允许识别部分嵌套的结构化数据。从这个意义上讲,它的目标和范围与XPath对XML的作用类似。GPath​通常用于处理XML,但它确实适用于任何对象图。在XPath使用类似文件系统的路径表示法(部分由斜线/​分隔的树层次结构)的情况下,GPath使用点对象表示法来执行对象导航。

例如,可以指定感兴趣对象或元素的路径:

  • a.b.c : 在xml中可以表示,在a中生成b中的所有c元素。
  • a.b.c​ : 在POJOS对象中可以表示,为a的所有b属性生成c属性。类似于:a.getB().getC()。

在这两种情况下,GPath​表达式都可以视为对象图上的查询。对于POJO,对象图通常由通过对象实例化和组合编写的程序构建;对于XML处理,对象图是解析XML文本的结果,通常使用XmlParser或XmlSlurper等类。有关在Groovy中使用XML的更多详细信息,请参阅处理XML。

PS:这里就不详细介绍如何处理XML文件了。如果想了解XML文件的处理可以阅读:http://docs.groovy-lang.org/docs/groovy-4.0.6/html/documentation/#processing-xml。如果不想阅读该英文文档,可以等待我后续的相关介绍

当查询从XmlParser或XmlSlurper生成的对象图时,GPath表达式可以引用在元素上使用@符号定义的属性:

  • a["@href"]​ :类映射表示法,所有a元素的href属性。
  • a.'@href':属性表示法:表示这一点的另一种方法。
  • a.@href:直接表示法:另一种表达方式

PS:后面学习XML解析的时候将会详细介绍。这里简单说明一下。

2.2 对象导航

让我们看一个简单对象图上GPath​表达式的示例,即使用java反射获得的表达式。假设您在一个类的非静态方法中,该类具有另一个名为aMethodFoo的方法:

void aMethodFoo() { println "This is aMethodFoo." }

以下GPath表达式将获取该方法的名称:

assert ['aMethodFoo'] == this.class.methods.name.grep(~/.*Foo/)

更准确地说,上面的GPath表达式生成了一个字符串列表,每个字符串都是此上现有方法的名称,其中该名称以Foo结尾。

现在,假如Foo类中还有以下的几个方法:

void aMethodBar() { println "This is aMethodBar." }
void anotherFooMethod() { println "This is anotherFooMethod." }
void aSecondMethodBar() { println "This is aSecondMethodBar." }

则以下GPath​表达式将获得aMethodBar​ 和aSecondMethodBar 方法名称

assert ['aMethodBar', 'aSecondMethodBar'] as Set == this.class.methods.name.grep(~/.*Bar/) as Set

2.3 解构表达式

我们可以分解表达式this.class.methods.name.grep(~/.*Bar/)​来了解如何计算GPath:

  • this.class​:属性访问器,在这里等效于java中的this.getClass()方法,生成一个Class对象。
  • this.class.methods​:属性访问器,相当于this.getClass().getMethods()​生成一个Method对象数组。
  • this.class.methods.name​:对Method数组的每个元素应用属性访问器,并生成结果列表。
  • this.class.methods.name.grep(...)​:对this.class.methods​生成的列表的每个元素调用方法grep并生成结果列表。

GPath​表达式的一个强大特性是,集合的属性访问被转换为集合中每个元素的属性访问,结果被收集到集合中。因此,表达式this.class.methods.name可以用Java表示如下:

List<String> methodNames = new ArrayList<String>();
for (Method method : this.getClass().getMethods()) {
methodNames.add(method.getName());
}
return methodNames;

在存在集合的GPath表达式中也可以使用数组访问表示法:

assert 'aSecondMethodBar' == this.class.methods.name.grep(~/.*Bar/).sort()[1]

PS: 1.grep()方法是一个正则表达式方法,用于查找字符串,方法中的传参是正则匹配哦。

2.在GPath表达式中,数组访问从零开始。

2.4 GPath的XML导航

下面是一个XML文档和各种形式的GPath表达式的示例:

def xmlText = """
| <root>
| <level>
| <sublevel id='1'>
| <keyVal>
| <key>mykey</key>
| <value>value 123</value>
| </keyVal>
| </sublevel>
| <sublevel id='2'>
| <keyVal>
| <key>anotherKey</key>
| <value>42</value>
| </keyVal>
| <keyVal>
| <key>mykey</key>
| <value>fizzbuzz</value>
| </keyVal>
| </sublevel>
| </level>
| </root>
"""

定义了一个xmlText变量,它的参数内容是一个xml。下面,通过GPath导航配置进行相关内容的读取:

def root = new XmlSlurper().parseText(xmlText.stripMargin())
println(root.level.size()) //输出: 1 因为root下只有一个level
println(root.level.sublevel.size) //输出:2 因为level下面有两个sublevel
println(root.level.sublevel.findAll { it.@id == 1 }.size())//查找sublevel下id值为1的。 输出:1
println(root.level.sublevel[0].keyVal[0].ket.text()) //输出:mykey

3. 小结

本篇主要介绍了一下Groovy的表达式的定义和GPath表达式的简单定义。其中GPath是java中没有的写法。可以支持多级对象结构,也可以用于Json,XMl的解析中来。

以上相关内容可以参考Groovy官方文档:Groovy Language Documentation (groovy-lang.org)

下一篇继续学习语法的相关知识。如果觉得总结的还行希望能够点个赞谢谢。

责任编辑:武晓燕 来源: zinyan
相关推荐

2009-06-15 17:24:59

Groovy正则表达式

2024-02-02 12:41:33

表达式语法Cron

2010-07-13 17:03:53

Perl正则表达式

2010-07-28 11:06:41

Flex正则表达式

2018-09-27 15:25:08

正则表达式前端

2016-11-10 16:21:22

Java 正则表达式

2011-04-22 11:07:24

groovyJava

2009-12-08 18:18:17

PHP表达式

2009-08-20 16:23:32

C#正则表达式语法

2014-01-05 17:41:09

PostgreSQL表达式

2009-08-26 16:17:23

C# Lambda表达

2009-08-11 13:00:41

C#正则表达式

2009-08-13 15:24:27

C#正则表达式

2009-09-08 09:32:13

正则表达式学习

2009-08-07 14:31:40

.NET正则表达式基础

2023-01-04 08:39:34

2011-08-29 18:43:45

MDX多维查询表达式

2009-08-14 16:50:59

C#正则表达式语法

2015-04-16 11:16:05

PHPPOSIX正则表达式

2010-02-24 17:13:47

点赞
收藏

51CTO技术栈公众号