成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

Groovy 語法 Promotion提升和Coercion強制轉換學習

開發 前端
本篇內容為Groovy學習第32篇,學習Groovy語法中的提升與強制轉換相關知識點。(Promotion和coercion),學習在Groovy中的各種數據類型的各種強制轉換和類型變換。

1. 介紹

本篇內容為Groovy學習第32篇,學習Groovy語法中的提升與強制轉換相關知識點。(Promotion和coercion)

學習在Groovy中的各種數據類型的各種強制轉換和類型變換。

如果不了解Groovy中的數據時如何進行轉換的,那么可以學習一下本篇內容,應該能夠給你一些參考。

2. 提升和強制轉換

2.1 數值轉換

整數提升:數字提升的規則在數學運算一節中有詳細說明。[4. Groovy語法-Number和Boolean數據類型學習 (zinyan.com)](https://zinyan.com/?p=389#2.5-數學運算)

主要就是下圖所示的,數值類型的轉換。


byte

char

short

int

long

BigInteger

float

double

BigDecimal

byte

int

int

int

int

long

BigInteger

double

double

BigDecimal

char


int

int

int

long

BigInteger

double

double

BigDecimal

short



int

int

long

BigInteger

double

double

BigDecimal

int




int

long

BigInteger

double

double

BigDecimal

long





long

BigInteger

double

double

BigDecimal

BigInteger






BigInteger

double

double

BigDecimal

float







double

double

double

double








double

double

BigDecimal









BigDecimal

不同數值之間的提升,是按照該表格的關系進行的。

2.2 閉包closure的類型轉換

在前面介紹閉包相關知識的時候,有介紹過閉包中的各種轉換,相關知識點可以通過:https://zinyan.com/?p=461,https://zinyan.com/?p=462,https://zinyan.com/?p=463了解。?

這里只是進行簡單的復習和介紹。

2.2.1 SAM單例對象,進行閉包轉換

SAM類型是定義單個抽象方法的類型。例如我們創建接口:它的入參是個T泛型。

interface Predicate<T> {
boolean accept(T obj)
}

具有單個抽象方法的抽象類:

abstract class Zinyan {
abstract String getName()
void hello() {
println "Hello, $name"
}
}

可以使用as運算符將任何閉包轉換為SAM類型:

Predicate filter = { it.contains 'G' } as Predicate
assert filter.accept('Groovy') == true

Greeter greeter = { 'Groovy' } as Greeter
greeter.hello() //輸出:Hello, Groovy

從Groovy 2.2.0 開始,as Type表達式是可選的。我們可以省略它,只需編寫:

Predicate filter = { it.contains 'G' }
assert filter.accept('Groovy') == true

Greeter greeter = { 'Groovy' }
greeter.hello() //輸出:Hello, Groovy

PS: 上面的  { it.contains 'G' }就是一個閉包對象哦

這意味著我們也可以使用方法指針,如下例所示:

boolean doFilter(String s) { s.contains('G') }

Predicate filter = this.&doFilter
assert filter.accept('Groovy') == true

Greeter greeter = GroovySystem.&getVersion
greeter.hello() //輸出:Hello, Groovy

2.2.2 調用接受帶有閉包的SAM類型的方法

關閉SAM類型強制的第二個也是可能更重要的用例是調用接受SAM類型的方法。設想以下方法:

public <T> List<T> filter(List<T> source, Predicate<T> predicate) {
source.findAll { predicate.accept(it) }
}

然后,可以使用閉包調用它,而無需創建接口的顯式實現:

assert filter(['Java','Groovy'], { it.contains 'G'} as Predicate) == ['Groovy']

從Groovy 2.2.0開始,還可以省略顯式強制,并像使用閉包一樣調用該方法:

assert filter(['Java','Groovy']) { it.contains 'G'} == ['Groovy']

這樣做的優點是允許我們在方法調用中使用閉包語法,也就是說,將閉包放在括號之外,從而提高了代碼的可讀性。

2.2.3 對任意類型的強制閉包

上面介紹了SAM單例對象的強制轉換,這里介紹其他的類型。

除了SAM類型之外,閉包還可以強制到任何類型,尤其是特定的接口。讓我們定義以下接口:

interface FooBar {
int foo()
void bar()
}

定義了一個接口對象,它有兩個方法分別是foo和bar。我們可以使用as關鍵字將閉包強制到接口中:

def impl = { println 'ok'; 123 } as FooBar

這將生成一個類,所有方法都使用閉包實現:

assert impl.foo() == 123
impl.bar() //輸出: ok

但也可以強制對任何類進行閉包。例如,我們可以用class替換我們定義的接口,而不改變assert斷言的結果:

class FooBar {
int foo() { 1 }
void bar() { println 'bar' }
}

def impl = { println 'ok'; 123 } as FooBar

assert impl.foo() == 123
impl.bar()

PS: 斷言結果不滿足是會出新錯誤并停止程序繼續執行的

2.3 Map強制轉換成類型

通常使用一個閉包來實現一個接口或一個具有多個方法的類是不可行的。作為替代方案,Groovy允許將Map?強制到接口或類中。在這種情況下,Map?的鍵被解釋為方法名,而值是方法實現。以下示例說明了將Map強制到迭代器中:

def map
map = [
i: 10,
hasNext: { map.i > 0 },
next: { map.i-- },
]
def iter = map as Iterator

當然,這是一個相當做作的例子,但說明了這個概念。我們只需要實現那些實際調用的方法,但如果調用的方法在映射中不存在,則會引發MissingMethodException或

UnsupportedOperationException,具體取決于傳遞給調用的參數,如下例所示:

interface X {
void f()
void g(int n)
void h(String s, int n)
}

x = [ f: {println "f called"} ] as X
x.f() // 正常的方法調用
x.g() // MissingMethodException 異常觸發
x.g(5) // UnsupportedOperationException 異常觸發

異常的類型取決于調用本身:

MissingMethodException:如果調用的參數與接口/類中的參數不匹配,就會觸發該異常警告。

UnsupportedOperationException:如果調用的參數與接口/類的重載方法之一匹配,就會觸發該異常警告。

2.4 String強制轉換成enum

Groovy允許透明String?(或GString)強制枚舉值。假設定義了以下枚舉:

enum State {
up,
down
}

則可以將字符串分配給枚舉,而不必使用顯式作為強制:

State st = 'up'
assert st == State.up

也可以使用GString作為值:

def val = "up"
State st = "${val}"
assert st == State.up

但是,這會引發運行時錯誤(IllegalArgumentException):

State st = 'not an enum value'

注意,也可以在switch語句中使用隱式強制:

State switchState(State st) {
switch (st) {
case 'up':
return State.down // 顯式賦值
case 'down':
return 'up' // 返回類型的隱式強制
}
}

特別是,請查看case?如何使用字符串常量。但如果調用一個使用帶有String?參數的枚舉的方法,則仍必須使用as作為強制:

assert switchState('up' as State) == State.down
assert switchState(State.down) == State.up
2.5 自定義類型強制轉換

類可以通過實現asType?方法來定義自定義強制策略。自定義強制是使用as?運算符調用的,并且從不隱式。例如,假設定義了兩個類,Polar和Cartesian,如以下示例所示:

class Polar {
double r
double phi
}
class Cartesian {
double x
double y
}

你想從極坐標轉換成笛卡爾坐標。一種方法是在Polar類中定義asType方法:

def asType(Class target) {
if (Cartesian==target) {
return new Cartesian(x: r*cos(phi), y: r*sin(phi))
}
}

這允許使用as強制運算符:

def sigma = 1E-16
def polar = new Polar(r:1.0,phi:PI/2)
def cartesian = polar as Cartesian
assert abs(cartesian.x-sigma) < sigma

把所有這些放在一起,Polar類看起來像這樣:

class Polar {
double r
double phi
def asType(Class target) {
if (Cartesian==target) {
return new Cartesian(x: r*cos(phi), y: r*sin(phi))
}
}
}

但也可以在Polar類之外定義asType,如果想為“封閉”類或不擁有源代碼的類定義自定義強制策略,例如使用元類:

Polar.metaClass.asType = { Class target ->
if (Cartesian==target) {
return new Cartesian(x: r*cos(phi), y: r*sin(phi))
}
}

PS: 自定義類型轉換主要的就是關鍵方法asType了。實現asType方法,然后自己就可以定義各種類型的轉換了。

2.6 類文本vs變量和as運算符

只有對類有靜態引用時,才能使用as關鍵字,如以下代碼所示:

interface Greeter {
void greet()
}
def greeter = { println 'Hello, Groovy!' } as Greeter // Greeter is known statically
greeter.greet()

但是,如果通過反射獲得類,例如通過調用class.forName,該怎么辦?

Class clazz = Class.forName('Greeter')

嘗試使用as關鍵字對類的引用將失敗:

greeter = { println 'Hello, Groovy!' } as clazz
// throws:
// unable to resolve class clazz
// @ line 9, column 40.
// greeter = { println 'Hello, Groovy!' } as clazz

會出現異常錯誤,因為as?關鍵字只對類文本有效。我們需要調用asType方法:

greeter = { println 'Hello, Groovy!' }.asType(clazz)
greeter.greet()

3. 小結

到這里,Groovy中有關于強制轉換和類型提升的相關知識就分享完畢了。以上內容可以通過Groovy官網文檔:

[Groovy Language Documentation (groovy-lang.org)](http://docs.groovy-lang.org/docs/groovy-4.0.6/html/documentation/#_promotion_and_coercion)深入學習。

責任編輯:武曉燕 來源: zinyan
相關推薦

2009-09-04 10:49:19

C#隱式轉換

2022-12-28 08:03:02

Groovy語法GPath

2023-01-17 14:01:19

JavaScript類型轉換字符串

2017-03-24 14:22:25

軟件開發互聯網計算機

2015-07-13 11:36:26

JavaavaScriptGroovy

2018-05-25 09:50:30

Java數據類型類型轉換

2011-06-17 16:42:23

C#

2023-01-04 08:39:34

2023-01-02 23:58:03

2022-12-26 08:36:53

Groovy語法控制結構

2010-09-08 13:14:03

CSS濾鏡

2012-02-16 11:38:23

ibmdw

2011-07-14 10:58:26

JavaScript強制類型轉換函數

2011-07-14 10:39:08

強制類型轉換函數C++

2009-09-04 09:00:29

Java基礎語法

2021-04-13 08:42:29

C語言數據類型轉換自動類型轉換

2010-05-28 19:39:28

MySQL 編碼轉換

2013-04-17 10:20:27

GroovyClassLoader

2009-08-18 15:00:00

C#強制轉換

2010-10-25 17:17:50

Oracle日期轉換函
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 黄色一级视频免费 | 九九亚洲 | 一级毛片成人免费看a | 狠狠狠色丁香婷婷综合久久五月 | 国产不卡在线观看 | 欧美电影免费观看高清 | 中文字幕日韩一区 | 久久久久免费精品国产小说色大师 | 欧美日韩精品亚洲 | 国产重口老太伦 | 亚洲成人免费视频在线观看 | 国产成人福利在线 | 国产成人在线视频免费观看 | 国产精品视屏 | 在线免费观看日本 | 成人av一区 | 91亚洲精品国偷拍自产在线观看 | 91视频网址| 久久区二区 | 在线播放国产一区二区三区 | 精品久久久久一区二区国产 | 日韩一区中文字幕 | 91精品国产综合久久久久 | 日本成人在线观看网站 | 婷婷色国产偷v国产偷v小说 | 亚洲精品久久久蜜桃 | 国产一区黄色 | 8x国产精品视频一区二区 | 欧美激情一区二区 | 国产精品99久久久久久久vr | 国产精品精品久久久久久 | 精品二区视频 | 成人免费在线视频 | 美女操网站 | h片在线免费看 | 色在线看 | 日韩中文字幕在线观看 | 综合久| 成年免费大片黄在线观看一级 | 成人精品一区二区户外勾搭野战 | 国产成人精品一区二区三区网站观看 |