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

RELATEED CONSULTING
相關咨詢
選擇下列產品馬上在線溝通
服務時間:8:30-17:00
你可能遇到了下面的問題
關閉右側工具欄

新聞中心

這里有您想知道的互聯(lián)網營銷解決方案
Groovy語法Promotion提升和Coercion強制轉換學習

1. 介紹

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

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

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

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

2. 提升和強制轉換

2.1 數(shù)值轉換

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

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

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的類型轉換

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

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

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

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

interface Predicate {
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  List filter(List source, Predicate predicate) {
source.findAll { predicate.accept(it) }
}

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

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

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

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

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

2.2.3 對任意類型的強制閉包

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

除了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斷言的結果:

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

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

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

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

2.3 Map強制轉換成類型

通常使用一個閉包來實現(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)那些實際調用的方法,但如果調用的方法在映射中不存在,則會引發(fā)MissingMethodException或

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

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 異常觸發(fā)
x.g(5) // UnsupportedOperationException 異常觸發(fā)

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

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

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

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

但是,這會引發(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?如何使用字符串常量。但如果調用一個使用帶有String?參數(shù)的枚舉的方法,則仍必須使用as作為強制:

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

類可以通過實現(xiàn)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了。實現(xiàn)asType方法,然后自己就可以定義各種類型的轉換了。

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

只有對類有靜態(tài)引用時,才能使用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關鍵字對類的引用將失?。?/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?關鍵字只對類文本有效。我們需要調用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)深入學習。


標題名稱:Groovy語法Promotion提升和Coercion強制轉換學習
本文URL:http://m.5511xx.com/article/cdcohjg.html