日韩无码专区无码一级三级片|91人人爱网站中日韩无码电影|厨房大战丰满熟妇|AV高清无码在线免费观看|另类AV日韩少妇熟女|中文日本大黄一级黄色片|色情在线视频免费|亚洲成人特黄a片|黄片wwwav色图欧美|欧亚乱色一区二区三区

RELATEED CONSULTING
相關(guān)咨詢
選擇下列產(chǎn)品馬上在線溝通
服務(wù)時(shí)間:8:30-17:00
你可能遇到了下面的問(wèn)題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營(yíng)銷解決方案
Groovy語(yǔ)法Promotion提升和Coercion強(qiáng)制轉(zhuǎn)換學(xué)習(xí)

1. 介紹

本篇內(nèi)容為Groovy學(xué)習(xí)第32篇,學(xué)習(xí)Groovy語(yǔ)法中的提升與強(qiáng)制轉(zhuǎn)換相關(guān)知識(shí)點(diǎn)。(Promotion和coercion)

在潮安等地區(qū),都構(gòu)建了全面的區(qū)域性戰(zhàn)略布局,加強(qiáng)發(fā)展的系統(tǒng)性、市場(chǎng)前瞻性、產(chǎn)品創(chuàng)新能力,以專注、極致的服務(wù)理念,為客戶提供網(wǎng)站制作、成都做網(wǎng)站 網(wǎng)站設(shè)計(jì)制作按需制作,公司網(wǎng)站建設(shè),企業(yè)網(wǎng)站建設(shè),高端網(wǎng)站設(shè)計(jì),成都全網(wǎng)營(yíng)銷,成都外貿(mào)網(wǎng)站制作,潮安網(wǎng)站建設(shè)費(fèi)用合理。

學(xué)習(xí)在Groovy中的各種數(shù)據(jù)類型的各種強(qiáng)制轉(zhuǎn)換和類型變換。

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

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

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

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

主要就是下圖所示的,數(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ù)值之間的提升,是按照該表格的關(guān)系進(jìn)行的。

2.2 閉包c(diǎn)losure的類型轉(zhuǎn)換

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

這里只是進(jìn)行簡(jiǎn)單的復(fù)習(xí)和介紹。

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

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

interface Predicate {
boolean accept(T obj)
}

具有單個(gè)抽象方法的抽象類:

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

可以使用as運(yùn)算符將任何閉包轉(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表達(dá)式是可選的。我們可以省略它,只需編寫:

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

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

PS: 上面的  { it.contains 'G' }就是一個(gè)閉包對(duì)象哦

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

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類型的方法

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

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

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

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

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

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

這樣做的優(yōu)點(diǎn)是允許我們?cè)诜椒ㄕ{(diào)用中使用閉包語(yǔ)法,也就是說(shuō),將閉包放在括號(hào)之外,從而提高了代碼的可讀性。

2.2.3 對(duì)任意類型的強(qiáng)制閉包

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

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

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

定義了一個(gè)接口對(duì)象,它有兩個(gè)方法分別是foo和bar。我們可以使用as關(guān)鍵字將閉包強(qiáng)制到接口中:

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

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

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

但也可以強(qiáng)制對(duì)任何類進(jìn)行閉包。例如,我們可以用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é)果不滿足是會(huì)出新錯(cuò)誤并停止程序繼續(xù)執(zhí)行的

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

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

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

當(dāng)然,這是一個(gè)相當(dāng)做作的例子,但說(shuō)明了這個(gè)概念。我們只需要實(shí)現(xiàn)那些實(shí)際調(diào)用的方法,但如果調(diào)用的方法在映射中不存在,則會(huì)引發(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ù)不匹配,就會(huì)觸發(fā)該異常警告。

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

2.4 String強(qiáng)制轉(zhuǎn)換成enum

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

enum State {
up,
down
}

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

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

也可以使用GString作為值:

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

但是,這會(huì)引發(fā)運(yùn)行時(shí)錯(cuò)誤(IllegalArgumentException):

State st = 'not an enum value'

注意,也可以在switch語(yǔ)句中使用隱式強(qiáng)制:

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

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

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

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

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

你想從極坐標(biāo)轉(zhuǎn)換成笛卡爾坐標(biāo)。一種方法是在Polar類中定義asType方法:

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

這允許使用as強(qiáng)制運(yùn)算符:

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類看起來(lái)像這樣:

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,如果想為“封閉”類或不擁有源代碼的類定義自定義強(qiáng)制策略,例如使用元類:

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

PS: 自定義類型轉(zhuǎn)換主要的就是關(guān)鍵方法asType了。實(shí)現(xiàn)asType方法,然后自己就可以定義各種類型的轉(zhuǎn)換了。

2.6 類文本vs變量和as運(yùn)算符

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

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

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

Class clazz = Class.forName('Greeter')

嘗試使用as關(guān)鍵字對(duì)類的引用將失?。?/p>

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

會(huì)出現(xiàn)異常錯(cuò)誤,因?yàn)閍s?關(guān)鍵字只對(duì)類文本有效。我們需要調(diào)用asType方法:

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

3. 小結(jié)

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

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


名稱欄目:Groovy語(yǔ)法Promotion提升和Coercion強(qiáng)制轉(zhuǎn)換學(xué)習(xí)
文章來(lái)源:http://www.5511xx.com/article/cdcohjg.html