此文章主要寫了我在學(xué)習(xí)kotlin的歷程中的一些感悟和體會。供入門的同學(xué)參考畔派。
一铅碍、Kotlin優(yōu)點
- 1.擴展函數(shù)
- 2.可空性(避免空指針)
- 3.代碼簡潔,可讀性強
- 4.高度互操作性(Kotlin與Java混合編程)
- 5.函數(shù)式編程
1.擴展函數(shù)
我們可以給任何類添加函數(shù)线椰,而不需要繼承它
例如:給View函數(shù)添加擴展函數(shù)胞谈,控制View的可見性
view的可見性我們一般寫成
我們可以通過擴展函數(shù)來定義方法
現(xiàn)在我們就能直接通過調(diào)用方法來控制視圖的可見性
并且,我們在Java中也可以調(diào)用在Kotlin中定義的擴展函數(shù)憨愉。
擴展函數(shù)的本質(zhì)是靜態(tài)函數(shù)烦绳,它把調(diào)用對象當(dāng)做它的第一個參數(shù)
所以,如果剛剛我們的View擴展函數(shù)定義在ViewUtils.kt
文件中
那么配紫,我們在Java
文件中可以這樣調(diào)用
ViewUtilsKt.visiable(tbCommonRlSync)
2.可空性
可空性是Kotlin類型系統(tǒng)中幫助你避免NullPointException錯誤的特性径密。
Kotlin的變量類型包括可空類型和非空類型√尚ⅲ可空類型在編譯期會檢查Null情況
Kotlin中提供多種運算符享扔,幫助我們檢查可空類型變量的Null情況
- 安全調(diào)用運算符
?.
- Elvis運算符
?:
- 安全轉(zhuǎn)換運算符
as?
- 非空斷言
!!
-
let
函數(shù)
3.代碼簡潔,可讀性強
例如:創(chuàng)建一個對象
Java中的寫法
在kotlin文件中
再例如:我們在定義按鈕點擊事件時通常的寫法是
Button button = (Button)findViewById(R.id.button)
button.setOnClickListener(new View.OnClickListener() {
@Override public void onClick(View v) {
Toast.makeText(this,”Click The Button",Toast.LENGTH_SHORT);
}
});
而利用Kotlin+Extension+Anko可以簡化為
button.onClick{
toast(“Click The Button”);
}
4.與Java的互操作性
Kotlin與Java能夠進行混合編程植袍,在原有Java項目中使用Kotlin編程時惧眠,不需要將整個項目都轉(zhuǎn)成Kotlin。
(1)屬性讀寫
Kotlin可以自動識別Java中的getter/setter于个;在Java中可以過getter/setter操作Kotlin的屬性氛魁。
(2)關(guān)鍵字調(diào)用
Kotlin中定義的一些關(guān)鍵字是Java中沒有的,如果Java中使用這些關(guān)鍵字作為方法名览濒,那么在Kotlin中調(diào)用時呆盖,要加入轉(zhuǎn)義字符。如is關(guān)鍵字:
(3)平臺類型
Java 中的任何引用都可能是
null
贷笛,這使得 Kotlin 對來自 Java 的對象要求嚴(yán)格空安全是不現(xiàn)實的应又。 Java 聲明的類型在 Kotlin 中會被特別對待并稱為平臺類型。對這種類型的空檢查會放寬乏苦, 因此它們的安全保證與在 Java 中相同株扛。當(dāng)我們調(diào)用平臺類型變量的方法時尤筐,Kotlin 不會在編譯時報告可空性錯誤, 但在運行時調(diào)用可能會失敗洞就,因為空指針異撑璺保或者 Kotlin 生成的阻止空值傳播的斷言:
平臺類型表示法
用助記符!來表示平臺類型,如:
T!
表示T
或者T?
(4)可變參數(shù)
Kotlin調(diào)用Java中含有可變參數(shù)的函數(shù)時旬蟋,可以用展開運算符*
例如:在Java中定義方法
public void removeIndicesVarArg(int... indices)
在kotlin中調(diào)用就要用到展開運算符
javaObj.removeIndicesVarArg(*array)
5.函數(shù)式編程
Kotlin支持面向?qū)ο蠛秃瘮?shù)式兩種編程風(fēng)格油昂。
函數(shù)式編程的核心是
- 頭等函數(shù)——把函數(shù)當(dāng)作值來使用,可以用變量來保存它倾贰,把它當(dāng)作參數(shù)傳遞冕碟,或者當(dāng)作其他函數(shù)的返回值。
- 不可變性——使用不可變對象匆浙,保證他們的狀態(tài)在創(chuàng)建之后不能再變化
- 無副作用——使用的是純函數(shù)安寺。此函數(shù)在輸入相同時會產(chǎn)生同樣的結(jié)果,并且不會修改其他對象的狀態(tài)首尼,也不會與外面的世界交互挑庶。
二、學(xué)習(xí)歷程
1.技術(shù)背景
書籍
- kotlin in action(1-2周)
主要講解Kotlin的入門基礎(chǔ)软能,推薦指數(shù)五顆星 - kotlin-for-android-developers-zh(2天)
主要講解kotlin的實踐迎捺,對基礎(chǔ)知識沒有過多的講解,推薦指數(shù)四顆星 - kotlin崛起:次世代Android開發(fā)(1天)
主要看的是Anko Layout DSL部分埋嵌,推薦指數(shù)三顆星 - kotlin-reference-chinese (http://www.kotlincn.net/docs/reference/) (1天)
kotlin的官方文檔破加,主要看的是java與kotlin的互操作性俱恶,推薦指數(shù)五顆星
2.遇到過的問題
(1) kotlin中使用Retrofit的通配符問題
Retrofit請求的時候雹嗦,要先定義一個接口
在Java中 代碼可以正常執(zhí)行
在kotlin中代碼不能正常執(zhí)行
Retrofit在執(zhí)行此方法時,會檢查參數(shù)的類型合是。雖然kotlin的Any類似于Java的Object了罪,但是這里的會被編譯成通配符?。Retrofit檢查到類型為通配符聪全,會報出異常泊藕,導(dǎo)致代碼不能正確的執(zhí)行。
這時候我們可以添加@JvmSuppressWildcards
注解
@JvmSuppressWildcards
用來注解類和方法难礼,使得被標(biāo)記元素的泛型參數(shù)不會被編譯成通配符娃圆。這樣就可以保證代碼正常執(zhí)行
(2)數(shù)據(jù)庫框架GreenDao
,需要在實體類中添加注解生成對應(yīng)的Dao類
但是這個框架并不支持Kotlin的實體類蛾茉,所以在使用的時候讼呢,我們還是要將需要保存到數(shù)據(jù)庫的實體,以Java類的形式編寫谦炬。
(3)java調(diào)用Kotlin代碼時悦屏,可能會傳入一個空的變量节沦,由于是平臺類型的變量在編譯的時候并不會報錯,但是在運行期間會直接奔潰础爬。故我們在使用平臺類型的時候甫贯,要謹(jǐn)慎使用。
(4)kotlin與Databinding一起使用的話
需要在Gradle
文件中添加如下配置
kapt {
generateStubs = true
}
dependencies {
kapt 'com.android.databinding:compiler:3.0.0'
}
三看蚜、Kotlin實踐
利用kotlin來編寫一個小demo
功能簡介
- 利用kotlin來編寫一個小Demo叫搁,實現(xiàn)簡單的登錄功能和地區(qū)信息的增刪查改
- 利用
Anko Layout DSL
來替代XML文件編寫界面 - 使用
Extension
來訪問組件 - 使用擴展函數(shù)作為工具類
- 以
rxJava
+Retrofit
作為網(wǎng)絡(luò)框架,GreenDao
作為數(shù)據(jù)庫操作框架
1.登錄界面(Anko layout dsl)
編寫如圖一個登錄界面
用Anko Layout DSL來寫的話
- 其中
dip
函數(shù)是Anko庫中將dip
單位的值轉(zhuǎn)為像素單位的一個函數(shù) -
onClick
函數(shù)是Anko庫中對OnClickListener
接口的一個擴展函數(shù)
2.區(qū)域列表界面
編寫如圖一個區(qū)域列表界面
用Anko Layout DSL來寫的話
Anko Layout DSL優(yōu)缺點
- 優(yōu)點:
1.相比于Java代碼編寫的界面供炎,更加的簡潔常熙。所有的組件都是Anko庫中定義的擴展函數(shù),lambda表達式作為參數(shù)碱茁,可讀性強
2.相比較與XML文件裸卫,這種編寫界面的方式更易于擴展,代碼易于重用 - 缺點:
1.現(xiàn)階段的Anko Layout Preview
工具還不太成熟纽竣,預(yù)覽界面不能實時刷新墓贿。
2.組件Id
需要自己定義,通過Id
獲取組件很麻煩蜓氨,也沒辦法與Extension
一起使用
下面看下Extension的使用
3.用Extension來訪問XML中的組件
先用XML編寫一個Dialog彈窗聋袋,如圖
XML文件如下
我們在Kotlin文件中,導(dǎo)入該布局
就能直接利用Id訪問組件
這樣我們就能擺脫大量的findViewById
代碼
4.非空性
-
let
函數(shù) 保證接收到的參數(shù)為空時穴吹,不執(zhí)行任何操作
5.擴展函數(shù)
為Activity定義擴展函數(shù)幽勒,用于添加Fragment
在Activity中可以直接使用addFrg添加Fragment
6.函數(shù)式編程
這里將接口返回的List做適當(dāng)?shù)奶幚恚胊sSequence將數(shù)組轉(zhuǎn)換成序列的形式
filter
函數(shù)主要是從集合中移除不想要的元素
map
函數(shù)主要是 對集合中每一個元素應(yīng)用給定的函數(shù)并把結(jié)果收集到一個新的集合
apply
函數(shù)是把第一個參數(shù)轉(zhuǎn)換成第二個參數(shù)傳給它的lambda
接收者港令,并返回作為實參傳遞給它的對象啥容。
最后用toList
函數(shù)將序列轉(zhuǎn)換為數(shù)組。
總結(jié)
- Kotlin編程使我們的代碼變得更加簡潔顷霹,可讀性強咪惠,便于我們代碼的review
- 可空性的處理極大的減少了我們代碼中NPE的風(fēng)險
- 擴展函數(shù)的存在,讓我們能夠方便的擴展API
- kotlin與Java高度的互操作性使我們可以在原有的項目中輕松的使用Kotlin
- Kotlin中大量的庫函數(shù)淋淀,極大的減少了我們的工具類