日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

java and dsl_Groovy语法糖以及DSL

發(fā)布時間:2024/9/27 编程问答 33 豆豆
生活随笔 收集整理的這篇文章主要介紹了 java and dsl_Groovy语法糖以及DSL 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

前言

Why

初次接觸到Groovy是在實(shí)習(xí)中接觸到一個 純Groovy寫的項目,當(dāng)時看了下這不就是沒有分號的Java么,而且也是有年紀(jì)的語言了,并不想投入時間學(xué)習(xí)。后來工作中越來越多的看到Groovy的身影,Gradle,Spring Cloud Contract等等都支持Groovy作為DSL(領(lǐng)域?qū)S谜Z言),同時Groovy在測試領(lǐng)域也有一席之地,因為語法簡單,可以很快捷的編寫Test Case,總之可以把Groovy看作Java的小伙伴,好幫手。

What

Groovy是JVM平臺上的一種面向?qū)ο笄彝瑫r支持靜態(tài)動態(tài)的腳本語言,語法和Java區(qū)別不大,提供了一些語法糖,代碼的表達(dá)能力更強(qiáng)。默認(rèn)小伙伴們都已經(jīng)有了Java基礎(chǔ),本文主要介紹Groovy比Java多出的語法糖,以及使用較多的DSL。

語法糖

大致了解一些語法糖可以更舒服的看DSL

可以用def關(guān)鍵字定義變量和方法,編譯期做類型推斷

多變量同時創(chuàng)建

def (aa, bb) = [1, 2]

范圍創(chuàng)建

int[] range = 0..10;

支持for in寫法

for(variable in range) {

statement #1

statement #2

}

方法參數(shù)支持默認(rèn)值

def someMethod(parameter1, parameter2 = 0, parameter3 = 0) {

// Method code goes here

}

字符串支持單引號和雙引號,類似于shell,python,雙引號中可識別變量

列表創(chuàng)建

List strings = ["g", "r", "o", "o", "v", "y"]

map創(chuàng)建

Map stringMap = ["name": "wang", "age": "99"]

正則表達(dá)式,~后面直接跟正則語句,可直接用于判斷

if ( "Groovy" =~ "^G")

trait關(guān)鍵字聲明一個可以有屬性和默認(rèn)實(shí)現(xiàn)的接口,Java8之后的接口也都能達(dá)到同樣效果

支持閉包,自己Call自己

def closure = { param -> println "Hello ${param}" };

closure.call("World");

10.times {num -> println num}

函數(shù)科里化賊方便

def cl1 = {int a, b, c ->

a + b + c

}

def cl1Curry1 = cl1.curry(1)

調(diào)用shell方便

println "ls -l".execute().text

instanceof可以簡寫成in

DSL

鏈?zhǔn)秸{(diào)用

在不產(chǎn)生歧義的情況下我們可以省略方法調(diào)用中的括號,使代碼更像說話

// equivalent to: turn(left).then(right)

turn left then right

// equivalent to: take(2.pills).of(chloroquinine).after(6.hours)

take 2.pills of chloroquinine after 6.hours

// equivalent to: paint(wall).with(red, green).and(yellow)

paint wall with red, green and yellow

// with named parameters too

// equivalent to: check(that: margarita).tastes(good)

check that: margarita tastes good

// with closures as parameters

// equivalent to: given({}).when({}).then({})

given { } when { } then { }

運(yùn)算符重載

Operator

Method

a + b

a.plus(b)

a - b

a.minus(b)

a * b

a.multiply(b)

a ** b

a.power(b)

a / b

a.div(b)

a % b

a.mod(b)

a | b

a.or(b)

a & b

a.and(b)

a ^ b

a.xor(b)

a++ or ++a

a.next()

a-- or --a

a.previous()

a[b]

a.getAt(b)

a[b] = c

a.putAt(b, c)

a << b

a.leftShift(b)

a >> b

a.rightShift(b)

a >>> b

a.rightShiftUnsigned(b)

switch(a) { case(b) : }

b.isCase(a)

if(a)

a.asBoolean()

~a

a.bitwiseNegate()

-a

a.negative()

+a

a.positive()

a as b

a.asType(b)

a == b

a.equals(b)

a != b

! a.equals(b)

a <=> b

a.compareTo(b)

a > b

a.compareTo(b) > 0

a >= b

a.compareTo(b) >= 0

a < b

a.compareTo(b) < 0

a <= b

a.compareTo(b) <= 0

腳本基類

我們運(yùn)行的Groovy腳本在編譯過程中都自動繼承了 groovy.lang.Script 這個抽象類,并把腳步內(nèi)容綁定到run方法中執(zhí)行。

可以通過創(chuàng)建一個Binding在腳本和基類中創(chuàng)建公用的變量

def binding = new Binding()

def shell = new GroovyShell(binding)

binding.setVariable('x',1)

binding.setVariable('y',3)

shell.evaluate 'z=2*x+y'

assert binding.getVariable('z') == 5

可以自定義基類

class BaseScript extends Script{

String name

public void greet() { println "Hello, $name!" }

@Override

Object run() {

greet()

}

}

@BaseScript demo.BaseScript baseScript

setName "100"

greet()

@DelegatesTo

是一個文檔與編譯時注釋,當(dāng)我們使用了委托模式去執(zhí)行閉包時,文檔生成,IDE以及類型推斷都無法準(zhǔn)確知道閉包具體被委托到哪里執(zhí)行,我們就需要使用此注解顯示聲明。

當(dāng)我們要實(shí)現(xiàn)如下效果時,我們需要定義一個email方法接受一個閉包,然后通過構(gòu)建模式創(chuàng)建一個EmailSpec,去初始化并且委托執(zhí)行閉包

email {

from 'dsl-guru@mycompany.com'

to 'john.doe@waitaminute.com'

subject 'The pope has resigned!'

body {

p 'Really, the pope has resigned!'

}

}

def email(@DelegatesTo(strategy=Closure.DELEGATE_ONLY, value=EmailSpec) Closure cl) {

// ...

}

當(dāng)我們要委托給方法的另一個參數(shù)時可以

def exec(@DelegatesTo.Target Object target, @DelegatesTo Closure code) {

// rehydrate方法創(chuàng)建一個閉包副本

def clone = code.rehydrate(target, this, this)

clone()

}

自定義編譯器

增加默認(rèn)導(dǎo)入,并且支持別名

import org.codehaus.groovy.control.customizers.ImportCustomizer

def icz = new ImportCustomizer()

// "normal" import

icz.addImports('java.util.concurrent.atomic.AtomicInteger', 'java.util.concurrent.ConcurrentHashMap')

// "aliases" import

icz.addImport('CHM', 'java.util.concurrent.ConcurrentHashMap')

// "static" import

icz.addStaticImport('java.lang.Math', 'PI') // import static java.lang.Math.PI

// "aliased static" import

icz.addStaticImport('pi', 'java.lang.Math', 'PI') // import static java.lang.Math.PI as pi

// "star" import

icz.addStarImports 'java.util.concurrent' // import java.util.concurrent.*

// "static star" import

icz.addStaticStars 'java.lang.Math' // import static java.lang.Math.*

可用于限制AST的級別,比如使用者不能用閉包,不允許導(dǎo)入其他包等等

構(gòu)建

Groovy內(nèi)置了很多好用的構(gòu)建器,具體使用查看官方教程

[官方教程](

總結(jié)

以上是生活随笔為你收集整理的java and dsl_Groovy语法糖以及DSL的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。