自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

Groovy 語(yǔ)法-控制結(jié)構(gòu):if,switch,for,try等知識(shí)

開發(fā) 前端
本篇內(nèi)容介紹到這里就結(jié)束了,大家重點(diǎn)了解控制結(jié)構(gòu)的相關(guān)寫法和實(shí)現(xiàn)邏輯以及標(biāo)簽的基本聲明方式就可以了。

1. 介紹

本篇內(nèi)容為Groovy學(xué)習(xí)第30篇內(nèi)容,從本篇開始將會(huì)學(xué)習(xí)Groovy語(yǔ)法中的控制結(jié)構(gòu)

例如:if/else,switch/case ,try/cathc 等等。

2. 控制結(jié)構(gòu)

控制結(jié)構(gòu)是指以某種順序執(zhí)行的一系列動(dòng)作,用于解決某個(gè)問(wèn)題。最基本的控制結(jié)構(gòu)分為:順序,選擇,循環(huán)。

2.1 條件控制 structures

Groovy中的條件控制語(yǔ)句和java中的是一樣的,也是if-else 和switch - case

2.1.1 if-else語(yǔ)句

Groovy支持來(lái)自Java的常用if - else語(yǔ)法。實(shí)現(xiàn)示例如下:

def x = false
def y = false

if ( !x ) {
x = true
}
println x //輸出 true


if ( x ) {
x = false
} else {
y = true
}
println x //輸出 false
println y //輸出: false

也支持常見的if else if 嵌套格式:

if ( ... ) {
...
} else if (...) {
...
} else {
...
}

2.1.2 switch-case 語(yǔ)句

Groovy中的switch語(yǔ)句向后兼容Java代碼;因此,您可以在多個(gè)匹配的情況下共享相同的代碼。

不過(guò)有一個(gè)區(qū)別是,Groovy switch語(yǔ)句可以處理任何類型的switch值,并且可以執(zhí)行不同類型的匹配。

示例如下:

def x = 1.23
def result = ""

switch (x) {
case "foo":
result = "found foo"
// lets fall through

case "bar":
result += "bar"

case [4, 5, 6, 'inList']:
result = "list"
break

case 12..30:
result = "range"
break

case Integer:
result = "integer"
break

case Number:
result = "number"
break

case ~/fo*/: // toString() representation of x matches the pattern?
result = "foo regex"
break

case { it < 0 }: // or { x < 0 }
result = "negative"
break

default:
result = "default"
}
println result //輸出: number

Switch支持以下幾種比較:

  • 如果switch的值是類的實(shí)例,則類用例值匹配。
  • 如果switch值的toString()表示與正則表達(dá)式匹配,則正則表達(dá)式大小寫值匹配。
  • 如果switch值包含在集合中,則集合用例值匹配。這也包括范圍(因?yàn)樗鼈兪橇斜?。
  • 如果調(diào)用閉包返回一個(gè)根據(jù)Groovy truth為true的結(jié)果,閉包大小寫值就匹配。

如果以上任何一個(gè)都沒有被使用,那么如果case值等于開關(guān)值,則case值匹配。

當(dāng)使用閉包大小寫值時(shí),默認(rèn)的it參數(shù)實(shí)際上是switch值(在我們的示例中是變量x)。

Groovy還支持如下示例所示的switch表達(dá)式:

def partner = switch(person) {
case 'Romeo' -> 'Juliet'
case 'Adam' -> 'Eve'
case 'Antony' -> 'Cleopatra'
case 'Bonnie' -> 'Clyde'
}

2.2 循環(huán)結(jié)構(gòu) Looping structures

簡(jiǎn)單介紹幾種常見的,也是必須掌握的循環(huán)結(jié)構(gòu),例如for,while,do while結(jié)構(gòu)寫法。

2.2.1 for循環(huán)語(yǔ)句

Groovy支持標(biāo)準(zhǔn)的Java 或 C 語(yǔ)言的for循環(huán):

String message = '' //創(chuàng)建一個(gè)變量
//通過(guò)for循環(huán) 循環(huán)4次進(jìn)行賦值操作。
for (int i = 0; i < 4; i++) {
message += 'zinyan '
}
prinlnt message //輸出:zinyan zinyan zinyan zinyan

也支持使用逗號(hào)分隔表達(dá)式的更復(fù)雜的Java經(jīng)典for循環(huán)形式。例子:

def facts = []
def count = 5
for (int fact = 1, i = 1; i <= count; i++, fact *= i) {
facts << fact //<< 表示給集合添加對(duì)象哦
}
println facts //輸出:[1, 2, 6, 24, 120]

上一篇介紹的多賦值操作與for語(yǔ)句也可以結(jié)合使用。29. Groovy 語(yǔ)法-變量定義與多重賦值 (zinyan.com)

PS:多賦值操作是從Groovy 1.6 版本開始支持的。如果你的編譯器報(bào)錯(cuò),那么說(shuō)明你的sdk版本太老了。

// 普通的進(jìn)行一個(gè)多賦值操作。 不懂的可以看第29篇的內(nèi)容。
def (String x, int y) = ['foo', 42]

// 多賦值操作和for循環(huán)結(jié)合使用:
def baNums = []
for (def (String u, int v) = ['bar', 42]; v < 45; u++, v++) {
baNums << "$u $v"
}
println baNums //輸出:['bar 42', 'bas 43', 'bat 44']

Groovy中的for循環(huán)要簡(jiǎn)單得多,可用于任何類型的數(shù)組、集合、Map等。

// iterate over a range
def x = 0
for ( i in 0..9 ) {
x += i
}
assert x == 45

// iterate over a list
x = 0
for ( i in [0, 1, 2, 3, 4] ) {
x += i
}
assert x == 10

// iterate over an array
def array = (0..4).toArray()
x = 0
for ( i in array ) {
x += i
}
assert x == 10

// iterate over a map
def map = ['abc':1, 'def':2, 'xyz':3]
x = 0
for ( e in map ) {
x += e.value
}
assert x == 6

// iterate over values in a map
x = 0
for ( v in map.values() ) {
x += v
}
assert x == 6

// iterate over the characters in a string
def text = "abc"
def list = []
for (c in text) {
list.add(c)
}
assert list == ["a", "b", "c"]

Groovy還支持使用冒號(hào)的Java冒號(hào)變體:for (char c: text) {}的循環(huán)結(jié)構(gòu)。

2.2.2 while 循環(huán)語(yǔ)句

Groovy像Java一樣支持常見的while{…}循環(huán):

def x = 0
def y = 5
//創(chuàng)建一個(gè)while循環(huán),每次循環(huán)會(huì)后y進(jìn)行減少,直到y(tǒng)小于等于0的時(shí)候,結(jié)束循環(huán)
while ( y-- > 0 ) {
x++
}
println x //輸出5

要注意,while的循環(huán)方法如果創(chuàng)建的條件不對(duì),是容易出現(xiàn)無(wú)限循環(huán)的,也就是死循環(huán)。

因?yàn)閣hile的條件一直為true的話,while就不會(huì)退出了。

2.2.3 do..while 循環(huán)語(yǔ)句

和while一樣,Groovy中的do...while 循環(huán)語(yǔ)句和java中的實(shí)現(xiàn)是一樣的。

def count = 5
def fact = 1
do {
fact *= count--
} while(count > 1)

println face //輸出 :120

3 異常-Exception

異常處理,其實(shí)也是控制結(jié)構(gòu)的一種。通過(guò)異常進(jìn)行強(qiáng)制結(jié)束程序的執(zhí)行順序。

Groovy沒有特殊的異常處理機(jī)制,它的Exception是和java的處理是一樣的。

3.1 try.. catch、finally語(yǔ)句

可以指定一組完整的try-catch-finally、try-catch或try-finally塊。

PS:如果完全不了解try塊的話,建議查詢java中異常捕獲機(jī)制try結(jié)構(gòu)的使用。

簡(jiǎn)單理解try語(yǔ)句就是,當(dāng)某段代碼出現(xiàn)了異常的時(shí)候,為了避免程序崩潰。我們主動(dòng)進(jìn)行防護(hù)。

就是使用try語(yǔ)句來(lái)實(shí)現(xiàn)的。catch只是出現(xiàn)了異常后我們需要程序執(zhí)行的內(nèi)容。

如果沒有異常,將會(huì)自動(dòng)按照順序執(zhí)行代碼(ps:不會(huì)執(zhí)行cath里面的代碼)。

簡(jiǎn)單的示例如下:

try {
'zinyan'.toLong() //把一個(gè)字符串轉(zhuǎn)long也會(huì)出現(xiàn)數(shù)據(jù)類型轉(zhuǎn)換異常
assert false // assert斷言必須執(zhí)行true,如果是false就會(huì)出現(xiàn)異常
} catch ( e ) {
assert e in NumberFormatException
}

如果想代碼不管是否出現(xiàn)異常,都進(jìn)行執(zhí)行。并根據(jù)異?;蚍钱惓5慕Y(jié)果進(jìn)行計(jì)算并執(zhí)行。那么我們可以使用finally子句

因?yàn)闊o(wú)論try子句中的代碼是否拋出異常,finally子句中的代碼都將始終執(zhí)行。

示例如下:

def z
try {
def i = 7, j = 0
try {
def k = i / j
assert false //never reached due to Exception in previous line
} finally {
z = 'reached here' //always executed even if Exception thrown
}
} catch ( e ) {
assert e in ArithmeticException
assert z == 'reached here'
}

3.2 多重catch子句

使用多捕獲塊(自Groovy 2.0以來(lái)),我們能夠定義幾個(gè)要被捕獲并由相同捕獲塊處理的異常:

try {
/* ... */
} catch ( IOException | NullPointerException e ) {
/* one block to handle 2 exceptions */
}

3.3 ARM Try 資源

對(duì)于自動(dòng)資源管理(ARM), Groovy通常為Java 7的try-with-resources語(yǔ)句提供更好的替代方案?,F(xiàn)在,遷移到Groovy并仍然希望使用舊風(fēng)格的Java程序員支持這種語(yǔ)法:

class FromResource extends ByteArrayInputStream {
@Override
void close() throws IOException {
super.close()
println "FromResource closing"
}

FromResource(String input) {
super(input.toLowerCase().bytes)
}
}

class ToResource extends ByteArrayOutputStream {
@Override
void close() throws IOException {
super.close()
println "ToResource closing"
}
}

def wrestle(s) {
try (
FromResource from = new FromResource(s)
ToResource to = new ToResource()
) {
to << from
return to.toString()
}
}

def wrestle2(s) {
FromResource from = new FromResource(s)
try (from; ToResource to = new ToResource()) { // Enhanced try-with-resources in Java 9+
to << from
return to.toString()
}
}

assert wrestle("ARM was here!").contains('arm')
assert wrestle2("ARM was here!").contains('arm')

將會(huì)輸出以下內(nèi)容:

ToResource closing
FromResource closing
ToResource closing
FromResource closing

4. 強(qiáng)大斷言 Power asserts

與Groovy共享assert關(guān)鍵字的Java不同,后者在Groovy中的行為非常不同。首先,Groovy中的斷言總是獨(dú)立于JVM的-ea標(biāo)志執(zhí)行。這使得它成為單元測(cè)試的首選?!皬?qiáng)大斷言”的概念與Groovy斷言的行為方式直接相關(guān)。

一個(gè)強(qiáng)大斷言被分解為三個(gè)部分:assert [left expression] == [right expression] : (optional message)

斷言的結(jié)果與在Java中得到的結(jié)果非常不同。如果斷言為真,那么什么也不會(huì)發(fā)生。如果斷言為假,那么它提供被斷言表達(dá)式的每個(gè)子表達(dá)式的值的可視化表示。例如:

assert 1+1 == 3

將會(huì)打印下面的內(nèi)容:

Caught: Assertion failed: 

assert 1+1 == 3
| |
2 false

Assertion failed:

assert 1+1 == 3
| |
2 false

at zinyan.run(zinyan.groovy:1)

當(dāng)表達(dá)式更復(fù)雜時(shí),權(quán)力斷言變得非常有趣,就像在下一個(gè)例子中:

def x = 2
def y = 7
def z = 5
def calc = { a,b -> a*b+1 }
assert calc(x,y) == [x,z].sum()

我們執(zhí)行上面的代碼后,將會(huì)輸出:

Caught: Assertion failed: 

assert calc(x,y) == [x,z].sum()
| | | | | | |
15 2 7 | 2 5 7
false

Assertion failed:

assert calc(x,y) == [x,z].sum()
| | | | | | |
15 2 7 | 2 5 7
false

at zinyan.run(zinyan.groovy:5)

如果不想要像上面那樣漂亮的打印錯(cuò)誤消息,可以通過(guò)更改斷言的可選消息部分來(lái)回退到自定義錯(cuò)誤消息,就像下面的例子:

def x = 2
def y = 7
def z = 5
def calc = { a,b -> a*b+1 }
assert calc(x,y) == z*z : 'Incorrect computation result'

將會(huì)輸出以下錯(cuò)誤內(nèi)容:

Caught: java.lang.AssertionError: Incorrect computation result. Expression: (calc.call(x, y) == (z * z)). Values: z = 5, z = 5
java.lang.AssertionError: Incorrect computation result. Expression: (calc.call(x, y) == (z * z)). Values: z = 5, z = 5
at zinyan.run(zinyan.groovy:5)

5. 標(biāo)簽聲明

任何語(yǔ)句都可以與標(biāo)簽相關(guān)聯(lián)。標(biāo)簽不影響代碼的語(yǔ)義,可用于使代碼更容易閱讀,如下例所示:

given:
def x = 1
def y = 2
when:
def z = x+y
then:
assert z == 3
zinyan:
println "zinyan.com"

在上面的示例中,given,when,then ,zinyan都是屬于標(biāo)簽。這些標(biāo)簽,并不會(huì)影響代碼的運(yùn)行結(jié)果和邏輯。

標(biāo)簽并沒有特殊的關(guān)鍵字,標(biāo)簽名稱可以隨意定義。

盡管沒有更改標(biāo)記語(yǔ)句的語(yǔ)義,但可以在break指令中使用標(biāo)簽作為跳轉(zhuǎn)的目標(biāo)。示例如下:

for (int i=0;i<10;i++) {
for (int j=0;j<i;j++) {
println "j=$j"
if (j == 5) {
break exit
}
}
exit: println "i=$i"
}

PS:雖然支持這種寫法,但是Groovy官方不推薦大家這樣使用標(biāo)簽。因?yàn)槿菀自斐烧`解和歧義。

默認(rèn)情況下標(biāo)簽對(duì)代碼的語(yǔ)義沒有影響,但是它們屬于抽象語(yǔ)法樹(AST),因此AST轉(zhuǎn)換可以使用該信息對(duì)代碼執(zhí)行轉(zhuǎn)換,從而導(dǎo)致不同的語(yǔ)義。這就是Spock框架為簡(jiǎn)化測(cè)試所做的工作。

6. 小結(jié)

本篇內(nèi)容介紹到這里就結(jié)束了,大家重點(diǎn)了解控制結(jié)構(gòu)的相關(guān)寫法和實(shí)現(xiàn)邏輯以及標(biāo)簽的基本聲明方式就可以了。

對(duì)于斷言和特殊的標(biāo)簽使用場(chǎng)景,可以做一個(gè)擴(kuò)展知識(shí)點(diǎn)的學(xué)習(xí)。一般在實(shí)際工作中用到的比較少。

以上內(nèi)容的知識(shí)來(lái)源于Groovy官方文檔:Groovy Language Documentation (groovy-lang.org)的學(xué)習(xí)筆記。

責(zé)任編輯:武曉燕 來(lái)源: zinyan
相關(guān)推薦

2023-01-04 08:39:34

2022-12-28 08:03:02

Groovy語(yǔ)法GPath

2023-01-02 23:58:03

2010-05-07 17:06:41

Unix fsck

2021-04-20 19:23:07

語(yǔ)法switch-casePython

2022-12-29 08:16:45

Groovy語(yǔ)法coercion

2021-04-16 15:02:38

Python 開發(fā)編程語(yǔ)言

2021-04-19 11:45:31

Pythonswitch編程語(yǔ)言

2024-11-04 08:20:00

try-catch編程

2024-05-10 11:43:23

C#編程

2013-04-17 10:20:27

GroovyClassLoader

2009-07-07 14:21:00

JSP語(yǔ)法

2009-12-16 14:40:14

Ruby控制結(jié)構(gòu)

2010-07-15 10:22:23

Perl控制結(jié)構(gòu)

2010-07-16 09:50:23

Perl控制結(jié)構(gòu)

2010-09-07 10:33:04

CSS

2009-12-09 10:34:54

PHP基本語(yǔ)法結(jié)構(gòu)

2009-12-24 17:45:31

ADO查詢

2010-07-13 13:56:43

Perl foreac

2010-07-19 11:07:13

Perl控制結(jié)構(gòu)
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)