Kotlin也沒那么難(一)

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;
}

要點:

  1. kotlin中沒有基本數(shù)據(jù)類型(int顷蟆,float等)修壕,都是以對象形式存在(Int,F(xiàn)loat)损同,kotlin也沒有數(shù)組翩腐,以Array類存在
  2. kotlin以 fun 關(guān)鍵字開頭,而java以 返回類型 開頭膏燃,kotlin的 返回類型:返回類型 的形式銜接在函數(shù)聲明括號后
  3. kotlin的所有變量聲明都是 變量名: 變量類型 茂卦,java則是 變量類型 變量名
  4. kotlin也有三目運算符,不過寫法是 if (表達式) 表達式正確時的值 else 表達式錯誤時的值蹄梢,java則是 表達式 ? 表達式正確時的值 : 表達式錯誤時的值
  5. 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}")

要點:

  1. kotlin創(chuàng)建對象是 Xxx() 轿亮,java是** new Xxx();**
  2. kotlin調(diào)用屬性的getter方法直接 xxx.property
  3. 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;
}

要點:

  1. when不用java中的 break
  2. when用 -> 替代 java中的 case
  3. when用 else 替代java中的 default
  4. 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"
        }

要點:

  1. when表達式會把最后一行代碼的結(jié)果當為返回值(見people2的情況,沒有寫return谚攒,但是會返回"is people2")
  2. 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

  1. kotlin沒有 throws 關(guān)鍵字(想起java被throws支配的恐懼了么)
  2. 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編譯器會將該方法生成一系列重載方法


result.png

由于我這個例子中 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())

要點:

  1. 我們定義了一個add2函數(shù)用于將一個 數(shù)+2 并返回
  2. add2函數(shù)面前使用 Int. 表示該函數(shù)是對Int類的擴展(就像是Int類本身的方法一樣)
  3. add2函數(shù)體內(nèi)的this其實就是調(diào)用該方法的對象(本例中this就是0)
  4. this可以省略惜傲,就變成了 return +2
  5. java中調(diào)用就得寫成 KotlinDemoKt.add2(0) 其實就是被編譯成了靜態(tài)函數(shù)
  6. 如果Int類也有add2則優(yōu)先調(diào)用Int類的add2函數(shù),即成員方法優(yōu)先調(diào)用
  7. 如果子類和基類有同名的擴展函數(shù)贝攒,調(diào)用哪個擴展函數(shù)由調(diào)用對象的聲明類型決定
  8. 除了有擴展函數(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~

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末凤薛,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子诞仓,更是在濱河造成了極大的恐慌缤苫,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,997評論 6 502
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件墅拭,死亡現(xiàn)場離奇詭異榨馁,居然都是意外死亡,警方通過查閱死者的電腦和手機帜矾,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,603評論 3 392
  • 文/潘曉璐 我一進店門翼虫,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人屡萤,你說我怎么就攤上這事珍剑。” “怎么了死陆?”我有些...
    開封第一講書人閱讀 163,359評論 0 353
  • 文/不壞的土叔 我叫張陵招拙,是天一觀的道長唧瘾。 經(jīng)常有香客問我,道長别凤,這世上最難降的妖魔是什么饰序? 我笑而不...
    開封第一講書人閱讀 58,309評論 1 292
  • 正文 為了忘掉前任,我火速辦了婚禮规哪,結(jié)果婚禮上求豫,老公的妹妹穿的比我還像新娘。我一直安慰自己诉稍,他們只是感情好蝠嘉,可當我...
    茶點故事閱讀 67,346評論 6 390
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著杯巨,像睡著了一般蚤告。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上服爷,一...
    開封第一講書人閱讀 51,258評論 1 300
  • 那天杜恰,我揣著相機與錄音,去河邊找鬼仍源。 笑死箫章,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的镜会。 我是一名探鬼主播,決...
    沈念sama閱讀 40,122評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼终抽,長吁一口氣:“原來是場噩夢啊……” “哼戳表!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起昼伴,我...
    開封第一講書人閱讀 38,970評論 0 275
  • 序言:老撾萬榮一對情侶失蹤匾旭,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后圃郊,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體价涝,經(jīng)...
    沈念sama閱讀 45,403評論 1 313
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,596評論 3 334
  • 正文 我和宋清朗相戀三年持舆,在試婚紗的時候發(fā)現(xiàn)自己被綠了色瘩。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,769評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡逸寓,死狀恐怖居兆,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情竹伸,我是刑警寧澤泥栖,帶...
    沈念sama閱讀 35,464評論 5 344
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響吧享,放射性物質(zhì)發(fā)生泄漏魏割。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,075評論 3 327
  • 文/蒙蒙 一钢颂、第九天 我趴在偏房一處隱蔽的房頂上張望钞它。 院中可真熱鬧,春花似錦甸陌、人聲如沸须揣。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,705評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽耻卡。三九已至,卻和暖如春牲尺,著一層夾襖步出監(jiān)牢的瞬間卵酪,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,848評論 1 269
  • 我被黑心中介騙來泰國打工谤碳, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留溃卡,地道東北人。 一個月前我還...
    沈念sama閱讀 47,831評論 2 370
  • 正文 我出身青樓蜒简,卻偏偏與公主長得像瘸羡,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子搓茬,可洞房花燭夜當晚...
    茶點故事閱讀 44,678評論 2 354

推薦閱讀更多精彩內(nèi)容