<p style="text-align:center;color:#42A5F5;font-size:2em;font-weight: bold;">前言
創(chuàng)新互聯(lián)建站擁有網(wǎng)站維護(hù)技術(shù)和項(xiàng)目管理團(tuán)隊(duì),建立的售前、實(shí)施和售后服務(wù)體系,為客戶提供定制化的成都網(wǎng)站制作、成都網(wǎng)站建設(shè)、網(wǎng)站維護(hù)、南充服務(wù)器托管解決方案。為客戶網(wǎng)站安全和日常運(yùn)維提供整體管家式外包優(yōu)質(zhì)服務(wù)。我們的網(wǎng)站維護(hù)服務(wù)覆蓋集團(tuán)企業(yè)、上市公司、外企網(wǎng)站、商城網(wǎng)站開(kāi)發(fā)、政府網(wǎng)站等各類型客戶群體,為全球千余家企業(yè)提供全方位網(wǎng)站維護(hù)、服務(wù)器維護(hù)解決方案。即使每天10點(diǎn)下班,其實(shí)需求很多,我也要用這腐朽的聲帶喊出:我要學(xué)習(xí),我要寫(xiě)文章??!
又是一篇Kotlin的文章,為啥...還不是因?yàn)楣ぷ餍枰?。毫無(wú)疑問(wèn),最好的學(xué)習(xí)方式是通過(guò)官方文檔去學(xué)習(xí)。不過(guò)個(gè)人覺(jué)得官方文檔多多少少有一些不夠高效。
中文官方文檔
因此這篇是從我學(xué)習(xí)的個(gè)人視角以文檔的形式去輸出Kotlin語(yǔ)言基礎(chǔ)的學(xué)習(xí)。
不扯淡了,開(kāi)整。
<p style="text-align:center;color:#42A5F5;font-size:2em;font-weight: bold;">正文
高階函數(shù)是將函數(shù)用作參數(shù)或返回值的函數(shù)。
個(gè)人為什么把這個(gè)語(yǔ)言特性放在第一位,因?yàn)槲矣X(jué)得這是我們Java語(yǔ)言中所不支持的。然而這個(gè)特性基本貫穿整個(gè)Kotlin語(yǔ)言體系。所以個(gè)人把它放到了第一位,也希望各位小伙伴能夠重視這個(gè)小小的特性。先看看一個(gè)小小的demo,感受一下這個(gè)特別特性:
// 函數(shù)定義
fun funtion(num: Int, innerFun: (Int) -> Int): Int {
return innerFun(num)
}
簡(jiǎn)單解釋一下上邊的代碼。我們先看函數(shù)定義,這里定義了一個(gè)名為funtion并且返回值為Int的函數(shù),此外這個(gè)函數(shù)接受一個(gè)Int參數(shù)和一個(gè)函數(shù)類型的參數(shù)(這個(gè)函數(shù)需要傳遞一個(gè)Int參數(shù),并且返回一個(gè)Int值)。
接下來(lái)我們調(diào)用一下:
// 函數(shù)調(diào)用
val result = funtion(1) {
it + 666
}
對(duì)于Lambda來(lái)說(shuō),入?yún)⑷绻且粋€(gè)的話可以用it來(lái)表示
說(shuō)實(shí)話,第一次我看到這種調(diào)用的時(shí)候,是一臉懵逼的。不知道剛?cè)肟拥男』锇槭遣皇呛臀乙粯拥母惺??因?yàn)檫@種寫(xiě)法包含小tips:
我們的innerFun是可以被簡(jiǎn)化為一個(gè)Lambda,而當(dāng)Lambda作為函數(shù)的最后一個(gè)參數(shù)時(shí),是可以將其寫(xiě)在函數(shù)之外的。也就是Demo中的funtion(1){}。
此外我們要注意一點(diǎn),這里我們的函數(shù)實(shí)例,并沒(méi)有return,這是因?yàn)?。lambda 表達(dá)式中的最后一個(gè)表達(dá)式是返回值
實(shí)際上這就是相當(dāng)于調(diào)用了funtion方法的倆個(gè)參數(shù),咱們換一種傳統(tǒng)的寫(xiě)法,二者是等價(jià)的:val inner = fun(num: Int): Int { return num + 1 } val result = funtion(1, inner)
OK,接下來(lái)咱們趁熱打鐵,再感受感受函數(shù)操作的“騷操作”。接下來(lái)我們看一看其實(shí)情況下的用法:
// 函數(shù)定義1 fun funtion(num: Int, innerFun: (Int, Int) -> Int): Int { return innerFun(num, num + 1) } // 函數(shù)調(diào)用1(上文提到,入?yún)?個(gè)可以用it表示,那么倆個(gè)或者多個(gè)呢?我們可以如下,自定義) val result = funtion(1) { num1, num2 -> num1 + num2 + 666 } // 函數(shù)調(diào)用2(除了Lambda的調(diào)用方式,我們還可以用匿名函數(shù),二者是一樣的) val result = funtion(1, fun(num1: Int, num2: Int): Int { return num1 + num2 + 666 }
OK,關(guān)于高階函數(shù)的內(nèi)容,就聊這么多,因?yàn)橛辛诉@個(gè)其實(shí),很多內(nèi)容也就很好上手了。接下來(lái)就讓我們一同看看基于高階函數(shù)的內(nèi)置封裝。
個(gè)人覺(jué)得,Kotlin操作符中。開(kāi)發(fā)中頗為常用的是集合操作符,比如我們有時(shí)需要對(duì)一些數(shù)據(jù)進(jìn)行連續(xù)的轉(zhuǎn)化,我們可能會(huì)使用RxJava;
Observable.create(new ObservableOnSubscribe<List<CustomModel>>() {
@Override
public void subscribe(ObservableEmitter<List<CustomModel>> e) throws Exception {
// 省略構(gòu)建List<CustomModel>
e.onNext(data);
}
}).flatMap(new Function<List<CustomModel>, ObservableSource<CustomModel>>() {
@Override
public ObservableSource<CustomModel> apply(List<CustomModel> customModels) throws Exception {
return Observable.fromIterable(customModels);
}
}).map(new Function<CustomModel, String>() {
@Override
public String apply(CustomModel customModel) throws Exception {
return customModel.name;
}
}).subscribe(new Consumer<String>() {
@Override
public void accept(String s) throws Exception {
// 操作s
}
});
這里簡(jiǎn)單,寫(xiě)了一個(gè)RxJava的Demo:我們有一個(gè)List集合,先把它一個(gè)個(gè)發(fā)送,然后把每一個(gè)數(shù)據(jù)轉(zhuǎn)成String,最后去String進(jìn)行處理。
而在Kotlin中,應(yīng)對(duì)上述的需求,我們?cè)撛趺醋??由于操作符的支持,我們可以極為方便的進(jìn)行這類操作:
val data = arrayListOf<CustomModel>(// ...省略構(gòu)建的過(guò)程)
val newData=data.map {
it.name
}.forEach {
// 操作it
}
用法很簡(jiǎn)單,乍一看很唬人。但是其實(shí)很簡(jiǎn)單,回憶一下我們?cè)匍_(kāi)篇奠定的高階函數(shù)的基礎(chǔ)。這里其實(shí)就是調(diào)用了data的擴(kuò)展函數(shù)map(拓展函數(shù)是一種語(yǔ)法,可以拓展現(xiàn)有的類。比如這個(gè)map就是拓展了Iterable,下文我們會(huì)展開(kāi)它的實(shí)現(xiàn))。對(duì)它進(jìn)行類型轉(zhuǎn)變,然后進(jìn)而調(diào)用forEach自動(dòng)對(duì)這個(gè)集合進(jìn)行遍歷。
接下來(lái)讓我們點(diǎn)進(jìn)去,看一看具體的實(shí)現(xiàn):
// 注意看,這里map的**返回值**,是一個(gè)List<R>,也就是說(shuō)最終將返回map后的類型集合。因此我們可以繼續(xù)進(jìn)行鏈?zhǔn)秸{(diào)用。
public inline fun <T, R> Iterable<T>.map(transform: (T) -> R): List<R> {
return mapTo(ArrayList<R>(collectionSizeOrDefault(10)), transform)
}
public inline fun <T, R, C : MutableCollection<in R>> Iterable<T>.mapTo(destination: C, transform: (T) -> R): C {
for (item in this)
destination.add(transform(item))
return destination
}
說(shuō)白了,這里的集合操作符就是把轉(zhuǎn)化的實(shí)現(xiàn)通過(guò)參數(shù)的形式暴露出來(lái),由我們自行去處理,其他的事情,有內(nèi)部封裝去做。
當(dāng)然,這其中還有很多有趣的操作符,各位小伙伴可以自行去了解。不過(guò)原理都是大同小異~
上述我們聊的是作用在集合上的操作符,說(shuō)白了。它們就是拓展在對(duì)應(yīng)集合類上的函數(shù)而已。那么可能有小伙伴會(huì)問(wèn),有沒(méi)有作用在對(duì)象上的?沒(méi)錯(cuò),是有的。也就是我們接下來(lái)要聊的:作用域函數(shù)。
其實(shí)很常見(jiàn):
"Kotlin".let{
it.toInt()
}
"Kotlin".run{
this.toInt()
}
"Kotlin".apply{
}
"Kotlin".also{
}
public inline fun <T, R> T.let(block: (T) -> R): R
public inline fun <T, R> T.run(block: T.() -> R): R
public inline fun <T> T.apply(block: T.() -> kotlin.Unit): T
public inline fun <T> T.also(block: (T) -> kotlin.Unit): T
咱們看一下,它們哥四個(gè)的定義,其實(shí)很清晰。這里以返回值的類型,倆倆分類:
不過(guò)即使沒(méi)有入?yún)?,也可以通過(guò)this,得到本身。
上述函數(shù)的作用還是挺方便的,比如:
Model model ;
// ...省略初始化過(guò)程
if(model!=null){
// 省略大段的操作邏輯
}
這種寫(xiě)法,在kotlin中可以這么寫(xiě):
model?.alse{
// 省略大段的操作邏輯
}
// 有需求我們可以繼續(xù)調(diào)用它的作用域函數(shù)
如果你還有一些else操作,那么沒(méi)轍了,kotlin中也只能老老實(shí)實(shí)if-else
當(dāng)然,還有一些有趣的作用域函數(shù),比如在Java中:
boolean isTure;
// 省略boolean判斷邏輯
if(isTure){
// 省略大段的操作邏輯
}
到Kotlin中可以這樣來(lái)搞:
某對(duì)象.takeIf{
// boolean判斷邏輯
}?.{
// 省略大段的操作邏輯
}
// 有需求我們可以繼續(xù)調(diào)用它的作用域函數(shù)
takeIf:會(huì)根據(jù)入?yún)⒌暮瘮?shù)的返回值(true/false),決定自己(takeIf)的返回值是null還是調(diào)用者。如果是false,那么就會(huì)返回null,因此這里使用?的方式繼續(xù)去調(diào)用后續(xù)操作。
我個(gè)人比較喜歡作用域函數(shù), 因?yàn)榭梢允÷院芏鄆f。接下來(lái)我們來(lái)?yè)Q個(gè)稍稍復(fù)雜的邏輯:已知一個(gè)方法,入?yún)⑹且粋€(gè)Model,我們要判斷當(dāng)這個(gè)Model對(duì)象的age屬性大于10,打印這個(gè)Model對(duì)象的名字。
對(duì)于Java來(lái)說(shuō),我們可能這么寫(xiě):
public void fun(Model model) {
// 寫(xiě)了3個(gè)if。
if (model != null) {
if (model.age>10){
if (model.name!=null){
// 打印model.name
}
}
}
}
class Model {
String name;
int age;
}
對(duì)于Kotlin來(lái)說(shuō),我們可以這么寫(xiě):
fun funtion(model : Model){
model?.takeIf{
it.age > 10
}?.let{
// 打印it.name
}
}
是不是簡(jiǎn)潔了很多?但是單說(shuō)簡(jiǎn)潔這種東西,似乎并沒(méi)有什么卵用...不過(guò)寫(xiě)起來(lái),真的很爽!不信,大家可以試試~~
<p style="text-align:center;color:#42A5F5;font-size:2em;font-weight: bold;">尾聲
這篇文章,想聊的內(nèi)容就這么多。個(gè)人認(rèn)為其實(shí)理解了高階函數(shù),(PS:不知道為啥起了個(gè)名叫高階函數(shù),整得好像很高級(jí)似的。)Kotlin就可以很快的上手,并且能感受到Kotlin寫(xiě)起來(lái)的爽快之處~
這里的確有些安利的意味。那是因?yàn)樽约鹤铋_(kāi)始對(duì)新技術(shù)其實(shí)接受度并不高,總認(rèn)為新東西有各種各樣的問(wèn)題...當(dāng)自己去了頭條之后,才發(fā)現(xiàn)身邊的同事那種高昂的學(xué)習(xí)勁頭,(Kotlin?對(duì)他們來(lái)說(shuō)不叫新東西...Jatpack,F(xiàn)lutter都已經(jīng)在線上項(xiàng)目中跑了)自己還有什么理由說(shuō):求求別更新了,我學(xué)不動(dòng)了...
還是那句話:干就完了!
另外有需要云服務(wù)器可以了解下創(chuàng)新互聯(lián)scvps.cn,海內(nèi)外云服務(wù)器15元起步,三天無(wú)理由+7*72小時(shí)售后在線,公司持有idc許可證,提供“云服務(wù)器、裸金屬服務(wù)器、高防服務(wù)器、香港服務(wù)器、美國(guó)服務(wù)器、虛擬主機(jī)、免備案服務(wù)器”等云主機(jī)租用服務(wù)以及企業(yè)上云的綜合解決方案,具有“安全穩(wěn)定、簡(jiǎn)單易用、服務(wù)可用性高、性價(jià)比高”等特點(diǎn)與優(yōu)勢(shì),專為企業(yè)上云打造定制,能夠滿足用戶豐富、多元化的應(yīng)用場(chǎng)景需求。
文章標(biāo)題:Kotlin快速入坑指南(干貨型文檔)-創(chuàng)新互聯(lián)
轉(zhuǎn)載來(lái)源:http://jinyejixie.com/article22/ggijc.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供網(wǎng)站排名、電子商務(wù)、全網(wǎng)營(yíng)銷推廣、網(wǎng)站建設(shè)、域名注冊(cè)、靜態(tài)網(wǎng)站
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)
猜你還喜歡下面的內(nèi)容