本文只是自學(xué)kotlin所做筆記毙石,并非全部原創(chuàng)
1、基本語(yǔ)法
var是變量废封,val是常量
kotlin中沒(méi)有new關(guān)鍵字
var datas:List<String> = ArrayList()
this: kotlin中this的指定方式是在this后加上@+類(lèi)名,如:
this@MainAcitivy
數(shù)組:
val names:Array = arrayOf("Kyo","Ryu","Iory")
val emptyStrings:Array = arrayOfNulls(10)
強(qiáng)制轉(zhuǎn)換:
java寫(xiě)法:
TextView tv = (TextView)view.findViewById(R.id.tv);
kotlin寫(xiě)法:
var tv:TextView = view.findViewById(R.id.tv) as TextView
2漂洋、空校驗(yàn)
Kotlin有兩種類(lèi)型:一個(gè)是非空引用類(lèi)型刽漂,一個(gè)是可空引用類(lèi)型弟孟。
var s: String = null
//報(bào)錯(cuò)拂募,提示“null不能是非空字符串的值”
var s: String? = null //允許為空
kotlin提供了一種方式庭猩,強(qiáng)制認(rèn)為變量不為null窟她,即 !!:
val srtLength = str!!.length
當(dāng)然這樣是不安全的,只有在你非常確定變量肯定不為空的時(shí)候蔼水,才能使用它震糖。kotlin提供一種判斷變量不為空的方法?.let{},如果非要使用!!趴腋,建議這樣寫(xiě):
str?.let {
val strLengh = str!!.length
}
對(duì)于可空引用吊说,如果希望調(diào)用它的成員變量或者成員函數(shù),直接調(diào)用會(huì)出現(xiàn)編譯錯(cuò)誤优炬,有三種方法可以調(diào)用:
(1)在調(diào)用前颁井,需要先檢查蠢护,因?yàn)榭赡転閚ull
(2)使用b?.length的形式調(diào)用雅宾,如果b為null,返回null葵硕,否則返回b.length
(3)使用b!!.length()的形式調(diào)用秀又,如果b為null,拋出空指針異常贬芥,否則返回b.length
3吐辙、三元運(yùn)算符
vall: Int =if(b !=null) b.length else-1
等價(jià)于
vall = b?.length ?: -1
(kotlin中if else 等價(jià)于java中的?: ,且 if else 后面可以是表達(dá)式)
4蘸劈、字符串拼接
Kotlin中支持在字符串中直接使用變量
// 字符串中直接使用變量
val name ="趙四"val str: String ="你好昏苏,$name"
// 定義一個(gè)User對(duì)象
class User constructor(varname : String,varage : Int)
// 字符串中使用User對(duì)象的屬性
var user: User = User("張三",23)
val toastStr: String ="這位是${user.name},今年${user.age}歲"
5威沫、定義方法(函數(shù))
Java 中方法需要定義到一個(gè)類(lèi)當(dāng)中贤惯,寫(xiě)法如下:
public String getString (String name){
return "張三"
}
Kotlin 中方法不一定要寫(xiě)在類(lèi)中,寫(xiě)法如下:
fun getString(name:String):String{
"張三"
}
注意到返回值的位置放到了參數(shù)之后棒掠。
也可以簡(jiǎn)化成
fun getString(name:String):String= "張三"
kotlin中函數(shù)也可以是一個(gè)變量
var method = { print("我是個(gè)方法")}
6孵构、函數(shù)的參數(shù)可以設(shè)置默認(rèn)值
fun reformat(str: String,
normalizeCase: Boolean = true,
upperCaseFirstLetter: Boolean = true,
divideByCamelHumps: Boolean = false,
wordSeparator: Char = ' ') {
......
}
// 直接使用默認(rèn)參數(shù)訪問(wèn),只需要傳第一個(gè)參數(shù)的值
reformat("str")
7烟很、如何定義靜態(tài)變量颈墅、方法
Java 的靜態(tài)方法或者變量只需要加一個(gè) static 即可:
public class Singleton{
private static Singleton instance = ...;
public static Singleton getInstance(){
...
return instance;
}
}
用 Kotlin 直譯過(guò)來(lái)就是:
class KotlinSingleton{
companion object {
private val kotlinSingleton = KotlinSingleton()
@JvmStaticfun
getInstance() = kotlinSingleton
}
}
8、擴(kuò)展函數(shù)
擴(kuò)展函數(shù)是在一個(gè)類(lèi)上增加一種新的行為雾袱,甚至我們沒(méi)有這個(gè)類(lèi)代碼的權(quán)限恤筛。擴(kuò)展函數(shù)的優(yōu)勢(shì)是它表現(xiàn)的像屬于這個(gè)類(lèi)一樣,不需要傳入這個(gè)類(lèi)的對(duì)象芹橡,而且可以使用this關(guān)鍵字和調(diào)用所有public方法毒坛。
fun Activity.toast(message: CharSequence, duration: Int = Toast.LENGTH_SHORT){
Toast.makeText(this, message, duration).show()
}
由于我們?cè)贑ontext上添加的這個(gè)擴(kuò)展函數(shù),那么他的子類(lèi)都可以直接使用,比如在activity煎殷、fragment中屯伞,如
toast("test", 1000)
toast("test")
擴(kuò)展函數(shù)并不是真正的修改了一個(gè)類(lèi),而是以靜態(tài)導(dǎo)入的方式來(lái)實(shí)現(xiàn)的豪直。擴(kuò)展函數(shù)可以被聲明在任何文件中劣摇,因此最好將一系列有關(guān)的擴(kuò)展函數(shù)定義在一個(gè)文件中。
9顶伞、Kotlin類(lèi)繼承
abstract //抽象類(lèi)標(biāo)示
final //標(biāo)示類(lèi)不可繼承饵撑,默認(rèn)屬性
enum //標(biāo)示類(lèi)為枚舉
open //類(lèi)可繼承剑梳,類(lèi)默認(rèn)是final的
annotation //注解類(lèi)
在類(lèi)的構(gòu)造函數(shù)之后使用“:”標(biāo)示繼承
class Student(name:String,age:Int):User(name,age){
}
所有類(lèi)定義時(shí)默認(rèn)是final屬性唆貌,不可被繼承。若需要繼承垢乙,使用open關(guān)鍵字進(jìn)行修飾锨咙。子類(lèi)重載方法使用override關(guān)鍵詞:
open class User{
open fun study(){}
fun run(){}
}
class Student:User{
override fun study(){}
}
當(dāng)類(lèi)同時(shí)繼承類(lèi)和實(shí)現(xiàn)接口,且有相同方法追逮,且相同方法都有實(shí)現(xiàn)時(shí)酪刀,需要在重載方法中調(diào)用所繼承的方法,使用關(guān)鍵詞super钮孵,T表示所繼承或?qū)崿F(xiàn)的接口:
open class User{
open fun study(){}
}
interface Reading{
fun study(){}
}
class Student:User(),Reading{
override fun study(){
super.study()
super.study() //與上者至少二選其一
}
}
10骂倘、多行輸入
var str = """
one
two
three
"""
//相當(dāng)于
var str1 = "one"+"/n"+"two"+"/n"+"three"
11、懶加載巴席,延遲加載
使用關(guān)鍵字lateinit修飾變量历涝,延遲初始化,lazeinit只能修飾var漾唉,不能修飾val荧库。lateinit修飾符只能修飾不可空類(lèi)型,并且不允許修飾基礎(chǔ)類(lèi)型(四類(lèi)八種基礎(chǔ)類(lèi)型int赵刑, double分衫,boolean)
lateinit var test: String//正確
lateinit val test:String//錯(cuò)誤
lateinit var test: Float//錯(cuò)誤
使用lazy懶加載
var getCity: String by lazy {
println("成都?xì)g迎你!")
"成都"
}
11般此、when蚪战,代替switch case
fun check(obj: Any) {
when(obj) {
0-> print("obj == 0")
1,2,3-> print("obj 是 1或2或3")
in3..10-> print("obj在3~10之間")
is User -> print("obj是User對(duì)象")
else-> {
print("不認(rèn)識(shí)這個(gè)對(duì)象")
throwException(obj.toString())
}
}
}
12、網(wǎng)絡(luò)請(qǐng)求
var text = URL(url).readText()
注意:readText不推薦結(jié)果很大的響應(yīng)铐懊。
anko提供了非常簡(jiǎn)單的DSL來(lái)處理異步屎勘。doAsync函數(shù)(async函數(shù)已經(jīng)棄用)用于在其他線程執(zhí)行代碼;uiThread則在主線程執(zhí)行代碼居扒,如:
doAsync{
var text = URL(url).readText()
Log.d(javaClass.simpleName, text)
uiThread{
toast("finish")
}
}
uiThread依賴于調(diào)用者惫谤,如果它被一個(gè)activity調(diào)用,那么當(dāng)activity.isFinishing()返回true号杏,uiTread就不會(huì)調(diào)用,這樣就防止了崩潰竿裂。
假如你想使用Future(java中關(guān)于線程的一個(gè)接口,用于獲取結(jié)果)來(lái)工作照弥,doAsync會(huì)返回一個(gè)Future腻异。而如果你需要一個(gè)返回結(jié)果的Future,可以使用doAsyncResult这揣。
13悔常、數(shù)據(jù)類(lèi)
data class Product(val date: Date, var price: Float, var detail: String)
復(fù)制數(shù)據(jù)類(lèi)
如果使用不可修改對(duì)象,如果要修改某個(gè)屬性必須新建一個(gè)對(duì)象给赞,使用copy可以簡(jiǎn)化机打,如:
var p1 = Product(Date(), 27.5f, "tiny robot")
var p2 = p1.copy(price = 30f)
映射數(shù)據(jù)類(lèi)
多聲明既映射對(duì)象的每一個(gè)屬性到一個(gè)變量中,如:
var p1 = Product(Date(), 27.5f, "tiny robot")
var (date, price, detail) = p1
上面這個(gè)多聲明會(huì)被編譯成:
var date = p1.compenent1()
var price = p1.compenent2()
var detail = p1.compenent3()
多聲明可以簡(jiǎn)化代碼片迅,比如在迭代一個(gè)map時(shí):
for((key, value) in map){
Log.d("map", "key: $key value: $value")
}