do not speak锅尘,show my code...
基本概念
函數(shù)
kotlin:
fun functionName(parameter1: Int, parameter2: Int): Int {
//該函數(shù)返回兩者最大值
return if (parameter1 > parameter2) parameter1 else parameter2
}
java:
Integer functionName(Integer parameter1, Integer parameter2) {
//該函數(shù)返回兩者最大值
return parameter1 > parameter2 ? parameter1 : parameter2;
}
要點:
- kotlin中沒有基本數(shù)據(jù)類型(int顷蟆,float等)修壕,都是以對象形式存在(Int,F(xiàn)loat)损同,kotlin也沒有數(shù)組翩腐,以Array類存在
- kotlin以 fun 關(guān)鍵字開頭,而java以 返回類型 開頭膏燃,kotlin的 返回類型以 :返回類型 的形式銜接在函數(shù)聲明括號后
- kotlin的所有變量聲明都是 變量名: 變量類型 茂卦,java則是 變量類型 變量名
- kotlin也有三目運算符,不過寫法是 if (表達式) 表達式正確時的值 else 表達式錯誤時的值蹄梢,java則是 表達式 ? 表達式正確時的值 : 表達式錯誤時的值
- kotlin語句末尾可以省略分號
表達式函數(shù)體
kotlin中if是表達式疙筹,而不是語句。語句是沒有自己的值禁炒,而表達式是有值的而咆。表達式可以作為其他表達式的一部分也可以作為函數(shù)的返回值。在kotlin中除了循環(huán)(for幕袱、do暴备、while)以外大多數(shù)控制結(jié)構(gòu)都是表達式。
所以上面的函數(shù)就可以簡化成以下代碼:
fun functionStruct(parameter1: Int, parameter2: Int) =
if (parameter1 > parameter2) parameter1 else parameter2
細心的朋友可能發(fā)現(xiàn)了上面的函數(shù)沒有聲明返回類型们豌,因為對于返回一個表達式的函數(shù)來說涯捻,編譯器會自動分析返回類型,術(shù)語叫 類型推導(dǎo)
變量
kotlin不會以變量類型開頭望迎,因為有些的變量聲明的類型是可以省略的
var number0 = 100
val number1 = 100
val number2 : Int = 100
val number3 //編譯不通過
val number4 : Int //編譯不通過
var 表示該變量是可變變量障癌,可以重新賦值
val 表示該變量是不可變變量,不可以重新賦值
字符串模板 "...${變量}..."
eg:var age = "my age is ${number0}"
辩尊,這種情況下大括號可以省略
如果是java會寫成 String age = "my age is " + number0;
eg:"...${list.get(0)}..."
這個時候大括號不能省
類和屬性
kotlin中默認public修飾符
kotlin定義一個類最簡單的方法就是class People(var name: String, val age: Int)
以上代碼定義了一個People類涛浙,該類有兩個屬性name和age
由于name被var修飾,所以kotlin會為name創(chuàng)建一個getter和一個setter方法
由于age被val修飾,所以kotlin會為name創(chuàng)建一個getter方法
使用起來很簡單
val my = People("name", 20)
my.name = "new Name"
println("my name is ${my.name} and my age is ${my.age}")
要點:
- kotlin創(chuàng)建對象是 Xxx() 轿亮,java是** new Xxx();**
- kotlin調(diào)用屬性的getter方法直接 xxx.property
- kotlin調(diào)用屬性的setter方法直接 xxx.property = value
注意:
如果寫成class People(name: String, age: Int)
疮薇,即省略了var和val,則這兩個變量都只是構(gòu)造函數(shù)用的臨時變量我注,也就是說kotlin不會再自動給People類創(chuàng)建name和age變量
自定義getter和setter方法
class People(var name: String, val age: Int) {
var desc: String = "這是我的個人描述"
get() {
print("調(diào)用了getter方法")
return "my name is $name and my age is $age"
}
set(value) {
print("調(diào)用了setter方法")
field = value
}
}
需要注意的是這里有個 field 變量按咒,這個變量術(shù)語叫做 幕后變量 ,這個后面我們會深入了解但骨,這里只需要知道把要更新的值賦予給該變量就OK啦
目錄和包
kotlin的包聲明形式和java一樣:package com.example.ice.kotlindemo
励七,不過有意思的是kotlin不強制包聲明和文件路徑一致,也就是說該kotlindemo.kt文件不必強制放在com/example/ice/目錄下奔缠。
kotlin文件可以同時聲明多個類呀伙,甚至還可以聲明函數(shù)和變量!java中只能在類中聲明函數(shù)添坊,并且一個java文件只能有一個public class的而且該class類名還必須和文件名一致
枚舉和When
enum
enum class Color {
BLUE, RED, GREEN
}
kotlin中enum是軟關(guān)鍵字,只有出現(xiàn)在class面前才有特殊意義箫锤,其他情況你甚至可以當一個變量使用 val enum: Color = Color.BLUE
when
when有點類似java中的switch贬蛙,但是when是表達式
kotlin:
fun testWhen(enum: Color) =
when (enum) {
Color.BLUE -> "blue"
Color.RED -> "red"
Color.GREEN -> "green"
else -> "default"
}
java:
public String testWhen(Color color) {
String returnValue;
switch (color) {
case RED:
returnValue = "red";
break;
case BLUE:
returnValue = "blue";
break;
case GREEN:
returnValue = "green";
break;
default:
returnValue = "default";
break;
}
return returnValue;
}
要點:
- when不用java中的 break
- when用 -> 替代 java中的 case
- when用 else 替代java中的 default
- when是表達式不是語句塊
在when分支上合并多個選項
when (enum) {
Color.BLUE, Color.RED -> "blue or red"
Color.GREEN -> "green"
else -> "default"
}
when結(jié)構(gòu)中可以使用任意對象
var people1: People = People("name1", 20)
var people2: People = People("name2", 20)
fun testWhen2(people: People) =
when (people) {
people1 -> "is people1"
people2 -> {
"is people2"
}
else -> "no match"
}
要點:
- when表達式會把最后一行代碼的結(jié)果當為返回值(見people2的情況,沒有寫return谚攒,但是會返回"is people2")
- when表達式某種情況下只有返回語句可以省略大括號(見people1的情況)
不帶參數(shù)的when
fun testWhen3() =
when {
1 > 2 -> print("1 > 2")
2 > 1 -> print("2 > 1")
else -> throw ArithmeticException("error")
}
類型轉(zhuǎn)換
kotlin使用 is 代替java的 instanceof 進行類型判斷
kotlin使用 as 進行顯示轉(zhuǎn)換 var num = 100 as Float
注意:as也可以用于導(dǎo)入語句 import xxx.xxx.People as P
這樣P就代表了People
循環(huán)
kotlin的循環(huán)比較于java來說沒有很大的改變阳准,但是多了一些關(guān)鍵字需要我們注意
var i = 0
for (i in 0..100) { //打印 01234..100
//for (i in 0 until 100) { //打印 01234..99
//for (i in 100 downTo 0 step 2) { //打印 1009896..0
print(i)
}
in 常常用來迭代list或map
val list = listOf(1, 2, 3)
for (i in list) {
print(i)
}
kotlin中使用 listOf 方法可以創(chuàng)建一個list
如果你想迭代list的同時獲取當前的index,可以使用如下寫法
for ((index, value) in list.withIndex()) {
//(index,value)的寫法專業(yè)術(shù)語叫做解構(gòu)聲明,后面我們會深入了解
print("index = $index and value = $value")
}
in 也可以用來判斷對象是否在集合中
if (2 in list) {
print("2 exist in list")
}
!in 關(guān)鍵字
Emm馏臭,這個看前面一個 ! 就知道是和 in 相反的結(jié)果了
try catch finally
- kotlin沒有 throws 關(guān)鍵字(想起java被throws支配的恐懼了么)
- try也是一個表達式
val myAge = try {
1 / 0
} catch (e: Exception) {
print(e)
} finally {
100
}
函數(shù)
集合創(chuàng)建
listOf(1, 2, 3)
mutableListOf(1, 2, 3)
setOf(1, 2, 3)
mutableSetOf(1, 2, 3)
mapOf(1 to "1", 2 to "2", 3 to "3")
mutableMapOf(1 to "1", 2 to "2", 3 to "3")
有mutable前綴的方法創(chuàng)建的集合野蝇,元素是可以增添、移除括儒、修改的
默認參數(shù)
fun defaultParaFun(para1: Int = 0, para2: Int, para3: Int) = para1 + para2 + para3
defaultParaFun(para2 = 2, para3 = 4)
我們給參數(shù)para1設(shè)置了默認值0
在調(diào)用該函數(shù)的時候我們對傳入的值進行了顯示的聲明參數(shù)绕沈,比如2就是參數(shù)para2的值,3就是參數(shù)para3的值帮寻,此時函數(shù)返回值為5(0+2+3)
有意思的是如果我們給所有參數(shù)都加默認值:
fun defaultParaFun(para1: Int = 0, para2: Int = 1, para3: Int = 2) = para1 + para2 + para3
defaultParaFun() // 0+1+2
defaultParaFun(para3 = 5) // 0+1+5
defaultParaFun(para2 = 5) // 0+5+2
defaultParaFun(para1 = 5, para2 = 5) // 5+5+2
同時java是不支持默認參數(shù)的乍狐,所以我們可以給方法加上@JvmOverloads注解。這樣的話kotlin編譯器會將該方法生成一系列重載方法
由于我這個例子中 defaultParaFun 是直接寫在 KotlinDemo.kt 文件中的(術(shù)語叫頂級函數(shù))固逗,所以java調(diào)用要使用 KotlinDemoKt.defaultParaFun 形式浅蚪,頂級函數(shù)是不是很像java中的靜態(tài)函數(shù)(kotlin是沒有static關(guān)鍵字的!)烫罩?
擴展函數(shù)
fun Int.add2(): Int {
return this + 2
}
print(0.add2())
要點:
- 我們定義了一個add2函數(shù)用于將一個 數(shù)+2 并返回
- add2函數(shù)面前使用 Int. 表示該函數(shù)是對Int類的擴展(就像是Int類本身的方法一樣)
- add2函數(shù)體內(nèi)的this其實就是調(diào)用該方法的對象(本例中this就是0)
- this可以省略惜傲,就變成了
return +2
- java中調(diào)用就得寫成
KotlinDemoKt.add2(0)
其實就是被編譯成了靜態(tài)函數(shù) - 如果Int類也有add2則優(yōu)先調(diào)用Int類的add2函數(shù),即成員方法優(yōu)先調(diào)用
- 如果子類和基類有同名的擴展函數(shù)贝攒,調(diào)用哪個擴展函數(shù)由調(diào)用對象的聲明類型決定
- 除了有擴展函數(shù)也有擴展屬性盗誊,不過擴展屬性必須要有g(shù)etter函數(shù),同時也不能初始化
可變參數(shù)
fun varargFun(vararg list: Int) {
print(list[0])
}
fun varargFun2(array: Array<Int>) {
listOf(*array)
}
varargFun(1, 2, 3)
vararg 關(guān)鍵字表示該參數(shù)是可變參數(shù)
* 關(guān)鍵字是展開運算符,在該例中把array展開為多個對象并用于構(gòu)造list
中綴調(diào)用
細心的朋友可能看到了之前我們定義map時用的是mapOf(1 to "1", 2 to "2", 3 to "3")
這里的to其實就是中綴調(diào)用浊伙,實際上就是一個to函數(shù)撞秋,中綴調(diào)用就是把方法名稱放在兩個參數(shù)中間,記得空格
我們可以看源碼 infix fun <A, B> A.to(that: B): Pair<A, B> = Pair(this, that)
其中尖括號里的是泛型嚣鄙,Pair是一個有兩個成員變量的類(一個叫first一個叫second)
我們先把infix關(guān)鍵字蓋住吻贿,其實這就是一個擴展函數(shù)對不對!
我們在加上infix關(guān)鍵字哑子,這個擴展函數(shù)就可以中綴調(diào)用了
需要注意的是舅列,infix只能用于只有一個參數(shù)的函數(shù)上
解構(gòu)聲明
val (para1, para2) = 1 to "1"
在這個例子中,para1就是1卧蜓,para2就是"1"
其實我們在之前循環(huán)的章節(jié)就有用到過解構(gòu)聲明
for ((index, value) in list.withIndex()) {
print("index = $index and value = $value")
}
解構(gòu)聲明不僅可以用在Pair和List也可以用在Map帐要,我們會在后面的文章中深入了解解構(gòu)規(guī)則
字符串
var string1 = "\\"
var string2 = """\"""
其實string1和string2都是表示
只不過普通的字符串包含轉(zhuǎn)義,\ 就是個轉(zhuǎn)義字符弥奸,所以 \\ 才能代表
而在多重引號字符串中就不包含轉(zhuǎn)義榨惠,所以可以直接用 \ 來表示
注:多重引號字符串用來寫正則特別方便
局部函數(shù)
這是我最喜歡的語法糖之一:函數(shù)里可以再定義函數(shù)
fun outer(){
print("outer invoke")
fun inner(){
print("inner invoke")
}
inner()
}
局部函數(shù)中可以訪問外部函數(shù)中的所有參數(shù)和變量(記得定義在局部函數(shù)之前哦)!
結(jié)語
通過本篇文章的學(xué)習我們已經(jīng)算 入門kotlin 了盛霎,下篇文章我會寫 類和接口赠橙,lambda編程以及可空性 相關(guān)》哒ǎ基本上這兩篇文章內(nèi)容熟練掌握就可以應(yīng)對開發(fā)需求期揪,之后會有篇幅講Kotlin的高階使用:反射、泛型等规个。
最后祝大家國慶Happy~