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

Groovy 語法 Promotion提升和Coercion強制轉(zhuǎn)換學習

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

1. 介紹

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

學習在Groovy中的各種數(shù)據(jù)類型的各種強制轉(zhuǎn)換和類型變換。

如果不了解Groovy中的數(shù)據(jù)時如何進行轉(zhuǎn)換的,那么可以學習一下本篇內(nèi)容,應該能夠給你一些參考。

2. 提升和強制轉(zhuǎn)換

2.1 數(shù)值轉(zhuǎn)換

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

主要就是下圖所示的,數(shù)值類型的轉(zhuǎn)換。


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

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

2.2 閉包closure的類型轉(zhuǎn)換

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

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

2.2.1 SAM單例對象,進行閉包轉(zhuǎn)換

SAM類型是定義單個抽象方法的類型。例如我們創(chuàng)建接口:它的入?yún)⑹莻€T泛型。

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

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

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

可以使用as運算符將任何閉包轉(zhuǎn)換為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 調(diào)用接受帶有閉包的SAM類型的方法

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

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

然后,可以使用閉包調(diào)用它,而無需創(chuàng)建接口的顯式實現(xiàn):

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

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

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

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

2.2.3 對任意類型的強制閉包

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

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

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

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

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

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

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

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

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

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

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

PS: 斷言結(jié)果不滿足是會出新錯誤并停止程序繼續(xù)執(zhí)行的

2.3 Map強制轉(zhuǎn)換成類型

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

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

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

UnsupportedOperationException,具體取決于傳遞給調(diào)用的參數(shù),如下例所示:

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

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

異常的類型取決于調(diào)用本身:

MissingMethodException:如果調(diào)用的參數(shù)與接口/類中的參數(shù)不匹配,就會觸發(fā)該異常警告。

UnsupportedOperationException:如果調(diào)用的參數(shù)與接口/類的重載方法之一匹配,就會觸發(fā)該異常警告。

2.4 String強制轉(zhuǎn)換成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

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

State st = 'not an enum value'

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

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

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

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

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

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

你想從極坐標轉(zhuǎn)換成笛卡爾坐標。一種方法是在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: 自定義類型轉(zhuǎn)換主要的就是關鍵方法asType了。實現(xiàn)asType方法,然后自己就可以定義各種類型的轉(zhuǎn)換了。

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

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

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

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

Class clazz = Class.forName('Greeter')

嘗試使用as關鍵字對類的引用將失?。?/p>

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

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

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

3. 小結(jié)

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

[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#隱式轉(zhuǎn)換

2022-12-28 08:03:02

Groovy語法GPath

2017-03-24 14:22:25

軟件開發(fā)互聯(lián)網(wǎng)計算機

2023-01-17 14:01:19

JavaScript類型轉(zhuǎn)換字符串

2015-07-13 11:36:26

JavaavaScriptGroovy

2023-01-04 08:39:34

2011-06-17 16:42:23

C#

2018-05-25 09:50:30

Java數(shù)據(jù)類型類型轉(zhuǎn)換

2022-12-26 08:36:53

Groovy語法控制結(jié)構(gòu)

2023-01-02 23:58:03

2011-07-14 10:58:26

JavaScript強制類型轉(zhuǎn)換函數(shù)

2012-02-16 11:38:23

ibmdw

2010-09-08 13:14:03

CSS濾鏡

2011-07-14 10:39:08

強制類型轉(zhuǎn)換函數(shù)C++

2021-04-13 08:42:29

C語言數(shù)據(jù)類型轉(zhuǎn)換自動類型轉(zhuǎn)換

2009-09-04 09:00:29

Java基礎語法

2009-08-18 15:00:00

C#強制轉(zhuǎn)換

2013-04-17 10:20:27

GroovyClassLoader

2010-10-25 17:17:50

Oracle日期轉(zhuǎn)換函

2024-02-28 09:57:30

C++類型強制轉(zhuǎn)換開發(fā)
點贊
收藏

51CTO技術棧公眾號