Jenkins pipeline 脚本语言学习支持

news2024/12/24 9:47:50

1 引言

Groovy是用于Java虚拟机的一种敏捷的动态语言,它是一种成熟的面向对象编程语言,既可以用于面向对象编程,又可以用作纯粹的脚本语言。 使用该种语言不必编写过多的代码,同时又具有闭包和动态语言中的其他特性。

Groovy是一种基础JVM(Java虚拟机)的敏捷开发语言,他结合了Python、Ruby和Smalltalk的特性,Groovy代码能够于Java代码很好的结合,也能用于扩展现有代码。 由于其运行在JVM的特性,Groovy可以使用其他Java语言编写法的库。

for(int i=0; i<10; i++) {
    ...
}

10.times{
    ...
}

在使用Groovy编程时,Java有的Groovy几乎都有。Groovy同样扩展了java.lang.Object类,Groovy类就是Java类,Java语义都保留下来了,所以使用Groovy编写的表达式和语句, 对于Java程序员而言,理解它没有任何障碍。
在这里插入图片描述
在这里插入图片描述
Groovy虽然支持Java的语法但它并没有强迫我们学习新的类和库,而是通过向JDK中各种类添加方法,所以说Groovy扩展了JDK,这些扩展称之为GDK (Groovy JDK)。

Java中可以使用java.lang.process与系统级进程进行交互,例如,我们在代码中调用git的help命令并把help的内容打印出来,用Java的实现代码如下:

package com.zs.groovy;


import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

public class ExecuterProcessor {
    public static void main(String[] args) {
        try {
            // 获取process实例
            Process process = Runtime.getRuntime().exec("git help");
            // 读取输入流
            BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
            String line = "";
            while ((line = reader.readLine()) != null) {
                System.out.println(line);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

转化为 groovy 语法:

print "git help".execute().text

2 基本语法

2.1 标识符

在这里插入图片描述

2.2 字符串

Groovy允许实例化java.lang.String类来定义一个字符串对象,同样地,也可以通过实例化groovy.lang.GString类定义一个字符串对象,两者可以混合使用。

def a = 'i am zhaoshuai-lc'
def b = '''
    i am zhaoshuai-lc
    and
    i am a male
'''
// 说明:用单引号或三个单引号定义的字符串不支持混合编程

def c = "hello zhaoshuai-lc"
> def name = "zhaoshuai-lc"
> def _name = "hello ${name}"
> print _name
hello zhaoshuai-lc

三个双引号引起来的字符串:
用"""引号引起来的字符串行为上和双引号引起来的字符串是一样的,不同之处在于它代表多行字符串,就像三个单引号定义的字符串。例如:

def name = 'zhaoshuai-lc'
def template = """
    Dear $name
    i love U
"""
print(template)

如果是使用内置变量类型定义的变量,一经定义,后面是不可以更改变量类型的。但是Groovy也提供了类似javascript中的any定义任意变量类型的关键字def。

class Example { 
   static void main(String[] args) { 
      def _Name = 1;
      _Name="it飞牛"; 
      println(_Name);
   } 
}
//打印如下:
it飞牛

在这里插入图片描述

2.3 数值类型

byte -这是用来表示字节值。例如2。
short -这是用来表示一个短整型。例如10。
int -这是用来表示整数。例如1234。
long -这是用来表示一个长整型。例如10000090。
float -这是用来表示32位浮点数。例如12.34。
double -这是用来表示64位浮点数,这些数字是有时可能需要的更长的十进制数表示。例如12.3456565。
char -这定义了单个字符文字。例如“A”。
Boolean -这表示一个布尔值,可以是true或false。
String -这些是以字符串的形式表示的文本。例如,“Hello World”。

在这里插入图片描述
在这里插入图片描述
不同类型数值进行算术运算的规则:
对于二元运算符,两个不同类型的数值进行运算后它们的结果按照以下规则确定
对于byte、char、short、int这几种类型之间运算的结果为int
涉及long与byte、char、short、int之间运算的结果为long
涉及BigInteger与其它类型数值之间的运算结果为BigInteger
BigDecimal与byte、char、short、int之间的运算结果为BigDecimal
float、double与BigDecimal之间的运算结果为double
两个BigDecimal之间的运算结果为BigDecimal

2.4 数组与集合

Groovy没有自己的集合类型,它的List类型实际上用的就是JDK中的java.util.List包。当我们定义一个集合对象,Groovy默认采用Java.util.ArrayList类型。

> def numbers = [1, 2, 3]
> assert numbers instanceof java.util.List
> assert numbers.size() == 3

也可以在集合中放置不同类型的元素,例如:

def numbers = [1, 2, 3, true, 'false']

默认定义的集合对象属于Java.util.ArrayList类,也可以用as运算符,强制定义List接口的其它实现类的对象,例如:

> def list = [1, 2, 3, 4] as LinkedList
> assert list instanceof LinkedList
> def list = [1, 2, 3, 4] as LinkedList
> assert 1 == list[0]
> assert 4 == list[-1]
> list << true
> print list[4]
true

Groovy 可以定义多维集合,例如:

def multi = [[0, 1], [2, 3]]

Groovy中数组和集合的表示方式相同,也就是说Groovy复用list的表示形式来表示数组,但必须显式的声明数组的类型,例如:

> String[] arrStr = ['zhaoshuai-lc', 'zhaoshuai-la', 'zhaoshuai-lb']
> assert arrStr instanceof String[]
> assert !(arrStr instanceof List)

使用as运算符,强制转化为要定义的类型:

> def intArr = [1, 2, 3] as int[]
> assert intArr instanceof int[]

也可以定义多维数组:

> def _matrix = new Integer[2][3]
> assert _matrix.size() == 2

声明时不指定数组元素个数:

> Integer[][] arr
> arr = [[1, 2, 3], [2, 3]]
> print arr.length
2

访问数组元素时按照和list—样的方式,使用下标运算符[],例如:

> String[] strArr = ['zjaosuia', 'dafas', 'erqrw']
> print strArr[2]
erqrw

Java 风格化:

> def primes = new int[]{2, 3, 4, 1, 6}
> assert primes.length == 5 && primes.sum() == 16
> 
> def pets = new String[]{'zhaoshuai', '-', 'lc'}
> assert pets.size() === 3 && pets.sum() == 'zhaoshuai-lc'
> 
> String[] groovyArr = ['zhaoshuaiA', '-A', 'lcA']
> assert groovyArr.every { it -> it.contains('A') }

2.4.1 List 语法详解

groovy 列表使用索引操作符 [] 索引。列表索引从 0 开始,指第一个元素。groovy 中的一个列表中的数据可以是任意类型。这 java 下集合列表有些不同,java 下的列表是同种类型的数据集合。
List.reverse() 可以实现列表反转。
调用 List.sort() 可以实现列表排序。

> def list1 = []
> def list2 = [1, 2, 3, 4]
> list2.add(12)
> list2.add(12)
> println list1.size()
> println list2.size()
0
6

1、搜索-find

class Main {
    static void main(String[] args) {
        def list = [1, 2, 3, 1, 2, 3];
        // find:返回第一个符合条件的项
        def find = list.find( item -> item == 1)
        assert 1 == find

        // findAll:返回所有符合条件的项
        def findA = list.findAll( item -> item == 1)
        assert [1, 1] == findA

        // findIndexOf:返回满足条件的第一个元素的下标值。
        def index = list.findIndexOf(item -> item == 1)
        assert 0 == index
    }
}

2、排序-sort、reverse

class Main {
    static void main(String[] args) {
        def list = [1, 2, 3, 1, 2, 3];
        // sort-正序排序
        print list.sort();
        // sort-倒叙排序
        print list.sort((a, b) -> b - a)
        // reverse:将原list倒序,返回一个新的list
        print list.reverse();
    }
}

3、返回新数组-collect、tail

class Main {
    static void main(String[] args) {
        def list = [1, 2, 3, 1, 2, 3];

        // collect:返回一个新的list,他可以接受一个闭包参数或者无参。类似js中map。it是闭包中自带的隐式变量;
        println list.collect(item -> item + 100)

        // tail:返回一个新的list,它包含list中的所有的元素(除了第一个元素)
        println list.tail(); // [2, 3, 1, 2, 3]
    }
}

4、遍历 each、eachWithIndex

class Main {
    static void main(String[] args) {
        def list = [1, 2, 3, 1, 2, 3];
        // each:普通的迭代遍历
        list.each(item -> print item)

        //eachWithIndex:他的作用和each一样,但是他要传入一个闭包,有两个参数,一个是值,一个是索引。
        list.eachWithIndex { int entry, int i -> println("${entry}--${i}")}
    }
}

every、any、first、last、max、min、count、unique

class Main {
    static void main(String[] args) {
        def list = [1, 2, 3, 1, 2, 3];
        // every:接收一个闭包,返回为一个布尔值,当所有条件都满足时才返回true
        println list.every(item -> item > 0)
        // any:和every用法一样,只要有一个为true,则返回true
        println list.any(item -> item > 0)
        //返回第一个数据
        println(list.first());
        //返回最后一个数据
        println(list.last());
        //返回最大值
        println(list.max());
        //返回最小值
        println(list.min());
        //返回总和
        println(list.sum());
        //返回某项出现的次数
        println(list.count(3));
        //返回去重后的数组
        println(list.unique());
    }
}

5、分组

class Main {
    static void main(String[] args) {
        def items = [[name: "tony", age: 4], [name: "tony", age: 5], [name: "alan", age: 16]]
        def groups = items.groupBy { it.name }
        println(groups);
        // [tony:[[name:tony, age:4], [name:tony, age:5]], alan:[[name:alan, age:16]]]
    }
}

6、包含

class Main {
    static void main(String[] args) {
        def list = [1, 2, 3, 1, 2, 3];
        def list2 = [1, 2, 3, 4];

        println(list.containsAll(list2));
        println(list2.containsAll(list));
    }
}

2.5 Map映射

Groovy的map对象 就是LinkedHashMap的实例
在这里插入图片描述

class Example { 
   static void main(String[] args) { 
      def mp = ["TopicName" : "Maps", "TopicDescription" : "Methods in Maps"] 
      println(mp.get("TopicName")); 
      println(mp.get("Topic")); 
   } 
}

2.6 对象运算符

安全导航运算符(safe navigation operator) 主要作用为避免出现NullPointerException异常,如果出现空指针异常,使用安全导航运算符将返回null,而不是抛出异常。例如:

> class Person{
>     int id
> 
>     Person(int id) {
>         this.id = id
>     }
> 
>     int getId() {
>         return id
>     }
> 
>     void setId(int id) {
>         this.id = id
>     }
> 
> }
> def person = new Person(3451)
> def _person = person.find{ item -> item.id == 345}
> println _person
> println _person?.id
null
null

直接字段访问运算符(Direct field access operator) 使用该运算符可以不用调用get方法而直接获取字段的值。例如:

> class User {
>     public String name;
>
>     User(String name) {
>         this.name = name;
>     }
>
>     String getName() {
>         "Name: ${name}"
>     }
> }
>
> def user = new User("Bob")
> print user.name
> assert user.name == 'Name: Bob'
Name: Bob

> class User {
>     public String name;
>
>     User(String name) {
>         this.name = name;
>     }
>
>     String getName() {
>         "Name: ${name}"
>     }
> }
>
> def user = new User("Bob")
> print user.@name
> assert user.@name == 'Bob'
Bob

2.7 正则表达式

Groovy使用~”pattern” 来支持正则表达式,它将使用给定的模式字符串创建一个编译好的Java Pattern 对象。Groovy也支持 =~(创建一个Matcher)和 ==~ (返回boolean,是否给定的字符串匹配这个pattern)操作符。

> import java.util.regex.Pattern
>
> def p = ~/foo/
> assert p instanceof Pattern
> def res = p.matcher('foo').matches()
> print res
true
> import java.util.regex.Matcher
>
> def text = 'i am your father'
> def res = text =~ /father/
> assert res instanceof Matcher
> print res.matches()
false
> import java.util.regex.Matcher
>
> def text = 'i am your father'
> def res = text ==~ /father/
> assert res instanceof Boolean
> print res
false

3 类与脚本

Groovy提供了两种代码方式,一种是脚本一种是类,首先我们定义一个名为Main.groovy的类。代码如下:

class Main{
    static void main(String[] args) {
        print 'hello zhaoshuai-lc'
    }
}

print 'hello zhaoshuai-lc'
print 'hello zhaoshuai-lc'

上面的脚本实由groovy.lang.Script类编译成一个class文件,把脚本代码拷贝到groovy.lang.Script类的run方法中进行执行,实际运行的代码形如下面的内容:

在这里插入图片描述
执行的步骤如下:
Main.class继承Script类
把脚本的主体内容复制到run方法内
然后自动生成main()方法,最后运行run()

方法 可以在脚本中定义方法,例如:

> int fib(int n) {
>     n < 2 ? 1 : fib(n - 1) + fib(n - 2)
> }
>
> assert fib(10) == 89

创建的脚本类在编译后会把脚本中的所有方法装配到run方法中,这些对于用户来说都是透明的。

变量 在脚本中定义变量无需声明变量的类型,例如:

int x = 1
int y = 2
assert x+y == 3
×= 1
y = 2
assert x+y == 3

这两者在语义上有一些差别,上面的例子中声明的变量属于局部变量,只在run方法内部可见,而下面的无声明变量定义对于其它方法可见, 这对于脚本与其它应用程序共享数据就显得很重要了。

Groovy类是数据的集合和对该数据进行操作的方法的载体,类的数据和方法用于表示问题域中的一些现实世界对象。 Groovy中的类声明了该类定义的对象的状态(数据)和行为。因此,Groovy类描述了该类的实例字段和方法。
在这里插入图片描述
在任何编程语言中,总是使用private关键字隐藏实例成员,通过提供getter和setter方法来相应地设置和获取实例变量的值。例如下面的代码:

在这里插入图片描述
内部类定义在另一个类中,外层类可以访问内部类,内部类也可以使用外层类的成员变量,即使是私有的。其它类不能访问内部类。内部类的示例如下:

class Main {
    static void main(String[] args) {
        def outer = new Outer()
        outer.name = 'zhaoshuai-lc'
        outer.callInnerMethods()
    }
}

class Outer {
    String name

    def callInnerMethods() {
        new Inner().methodInner()
    }

    class Inner {
        def methodInner() {
            print name
        }
    }
}

extends是用于继承类的关键字,我们通过一个示例介绍groovy中如何继承其它类:

class Main {
    static void main(String[] args) {
        def sub = new Sub('zhaoshuai-lc')
    }
}

class Outer {
    public String name
    Outer(String name) {
        print name
    }
}
class Sub extends Outer {
    Sub(String subName) {
        super(subName)
    }
}

抽象类表示通用概念,因此它不能被实例化,但可以被继承。抽象类中的抽象方法只有方法的定义而没有方法的实现,它的实现通过继承它的类来完成,定义抽象类通过关键字 abstract来声明,抽象方法也是同样的。

接口定义了类需要遵守的规范,接口仅定义需要实现的方法的列表,但是不定义方法实现。 接口需要使用interface关键字声明接口,接口的方法总是公开的,在接口中使用受保护或私有方法是一个错误。

class Example {
   static void main(String[] args) {
      Student st = new Student();
      st.StudentID = 1;
      st.Marks1 = 10;
      println(st.DisplayMarks());
   } 
} 

interface Marks { 
   void DisplayMarks(); 
} 

class Student implements Marks {
   int StudentID
   int Marks1;
	
   void DisplayMarks() {
      println(Marks1);
   }
}

4 闭包

闭包可以接收入参
闭包可以引用外部变量

class Example {     
   static void main(String[] args) {
      def str1 = "Hello";
      def clos = {param -> println "${str1} ${param}"}
      clos.call("World");
		
      // We are now changing the value of the String str1 which is referenced in the closure
      str1 = "Welcome";
      clos.call("World");
   } 
}

//打印
Hello World 
Welcome World

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/807192.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

大模型开发(十四):使用OpenAI Chat模型 + Google API实现一个智能收发邮件的AI应用程序

全文共1.2w余字&#xff0c;预计阅读时间约24~40分钟 | 满满干货(附代码)&#xff0c;建议收藏&#xff01; 本文目标&#xff1a;将Gmail API接入Chat模型&#xff0c;编写一个智能收发邮件的AI应用程序 代码下载点这里 一、背景 大模型应用开发从谷歌云入手进行学习和AI…

Python爬虫的urlib的学习(学习于b站尚硅谷)

目录 一、页面结构的介绍  1.学习目标  2.为什么要了解页面&#xff08;html&#xff09;  3. html中的标签&#xff08;仅介绍了含表格、无序列表、有序列表、超链接&#xff09;  4.本节的演示 二、Urllib  1.什么是互联网爬虫&#xff1f;  2.爬虫核心  3.爬虫…

Sentinel 容灾中心的使用

Sentinel 容灾中心的使用 往期文章 Nacos环境搭建Nacos注册中心的使用Nacos配置中心的使用 熔断/限流结果 Jar 生产者 spring-cloud-alibaba&#xff1a;2021.0.4.0 spring-boot&#xff1a;2.6.8 spring-cloud-loadbalancer&#xff1a;3.1.3 sentinel&#xff1a;2021.0…

如何快速模拟一个后端 API

第一步&#xff1a;创建一个文件夹&#xff0c;用来存储你的数据 数据&#xff1a; {"todos": [{ "id": 1, "text": "学习html44", "done": false },{ "id": 2, "text": "学习css", "…

只会“点点点”,凭什么让开发看的起你?

众所周知&#xff0c;如今无论是大厂还是中小厂&#xff0c;自动化测试基本是标配了&#xff0c;毕竟像双 11、618 这种活动中庞大繁杂的系统&#xff0c;以及多端发布、多版本、机型发布等需求&#xff0c;但只会“写一些自动化脚本”很难胜任。这一点在招聘要求中就能看出来。…

Android 面试题 优化 (一)

&#x1f525; Android性能优化指标 &#x1f525; ​ &#x1f525; 包体积优化 &#x1f525; 安装包的大小会影响用户的安装率&#xff0c;如果一个包的太大&#xff0c;用户安装的意愿会大大降低。 经过包分析可以看到&#xff0c;安装包最大的部分是资源和第三方库&#…

奥迪A3:最新款奥迪A3内饰设计及智能科技应用

奥迪A3一直以来都是奥迪的入门级车型&#xff0c;但这并不意味着它在科技和内饰方面会有所退步。最新款奥迪A3的内饰设计和智能科技应用让人们再次惊叹奥迪的创新能力。 内饰设计 奥迪A3最新款的内饰设计引入了奥迪最新的设计元素&#xff0c;比如8.8英寸的中控显示屏&#xf…

山西电力市场日前价格预测【2023-07-30】

日前价格预测 预测明日&#xff08;2023-07-30&#xff09;山西电力市场全天平均日前电价为287.10元/MWh。其中&#xff0c;最高日前电价为309.20元/MWh&#xff0c;预计出现在09: 15。最低日前电价为252.82元/MWh&#xff0c;预计出现在24: 00。 价差方向预测 1&#xff1a;实…

Dendrogram | 今天是人见人爱、花见花开的环形Dendrogram!~(附完整代码)

1写在前面 好长时间没更新了&#xff0c;这周真的是天天都在手术室度过&#xff0c;常讲到的一句话就是苦的一比啊。&#x1fae0; 很久没有见过外面的世界了&#xff0c;世界那么大&#xff0c;我也想去看看&#xff01;~&#x1f602; 废话太多了&#xff0c;今天的教程是环形…

网络安全/信息安全(黑客技术)自学笔记

一、网络安全基础知识 1.计算机基础知识 了解了计算机的硬件、软件、操作系统和网络结构等基础知识&#xff0c;可以帮助您更好地理解网络安全的概念和技术。 2.网络基础知识 了解了网络的结构、协议、服务和安全问题&#xff0c;可以帮助您更好地解决网络安全的原理和技术…

从分片传输到并行传输之大文件传输加速技术

随着大文件的传输需求越来越多&#xff0c;传输过程中也会遇到很多困难&#xff0c;比如传输速度慢、文件安全性低等。为了克服这些困难&#xff0c;探讨各种大文件传输加速技术。其中&#xff0c;分片传输和并行传输是两种比较常见的技术&#xff0c;下面将对它们进行详细说明…

WEB:Web_python_template_injection

背景知识 python模板注入 ssit 题目 打开题目&#xff0c;发现页面提示&#xff0c;翻译为python模板注入 先测试是否存在注入 可以发现被执行了 先查看所有的子类 payload {{[].__class__.__base__.__subclasses__()}} 利用site.Printer的os模块执行命令 payload {{.__…

CAN转EtherNet/IP网关can协议破解服务

JM-EIP-CAN 是自主研发的一款 ETHERNET/IP 从站功能的通讯网关。该产品主要功能是将各种 CAN 总线和 ETHERNET/IP 网络连接起来。 本网关连接到 ETHERNET/IP 总线中做为从站使用&#xff0c;连接到 CAN 总线中根据节点号进行读写。 技术参数 ETHERNET/IP 技术参数 网关做为 …

C# Socket实际应用案例与属性详解

引言 Socket是一个在网络编程中非常常见和重要的概念&#xff0c;它提供了一种通信机制&#xff0c;使不同的计算机之间可以进行数据传输。本文将介绍C#中Socket的实际应用案例&#xff0c;并对Socket的常用属性进行详细解析。 文章目录 1. Socket的实际应用案例2. Socket的属…

CAS比较并交换具体实现细节

线程2读取内存值到工作内存中&#xff0c;设置一个预估值与读入的值相等&#xff0c;线程1也同样读入。 线程2进行操作&#xff0c;之后在写入内存前&#xff0c;将预估值与内存值作比较&#xff0c;看内存值是否修改过。 如果线程2比较完相同&#xff0c;则修改内存值为1&am…

开源了!最强原创图解八股文面试网来袭

强烈推荐 Github上业内新晋的一匹黑马—Java图解八股文面试网—Java2Top.cn&#xff0c;图解 Java 大厂面试题&#xff0c;深入全面&#xff0c;真的强烈推荐~ 这是一个二本逆袭阿里的大佬根据自己秋招上岸所看过的相关专栏&#xff0c;面经&#xff0c;课程&#xff0c;结合自…

211. 添加与搜索单词 - 数据结构设计---------------字典树

211. 添加与搜索单词 - 数据结构设计 原题链接&#xff1a;完成情况&#xff1a;解题思路&#xff1a;参考代码&#xff1a; 原题链接&#xff1a; 211. 添加与搜索单词 - 数据结构设计 https://leetcode.cn/problems/design-add-and-search-words-data-structure/descriptio…

tinkerCAD案例:19. Move Circuit Assembly 移动电路组件

tinkerCAD案例&#xff1a;19. Move Circuit Assembly 移动电路组件 In this tutorial, you’ll learn how to add the Move circuit assembly to a design. 在本教程中&#xff0c;您将学习如何将移动电路装配体添加到设计中。 When you assemble the Move circuit assembly…

【Docker】Docker应用部署之Docker容器安装Tomcat

目录 一、搜索镜像 二、拉取镜像 三、创建容器 四、测试使用 一、搜索镜像 docker search tomcat 二、拉取镜像 docker pull tomcat:版本 三、创建容器 首先在宿主机创建数据卷的目录 mkdir /root/tomcat # 创建目录 cd /root/tomcat # 进入目录 docker run -id -…

解决mysqld服务启动失败

1、进程 首先查看下mysql进程: ps -aux | grep mysql有进程号 2、所有者和所属组为mysql 查看/usr/local/MySQL/data/mysqld.pid所有者和所属组是否为mysql 原来是权限有问题&#xff0c;那么更改权限&#xff08;还需要加权限&#xff09;3、 重新启动服务