1茵休、介紹Kotlin
Kotlin是jvm新的開(kāi)發(fā)語(yǔ)言薪棒。
谷歌推廣Kotlin作為其基于java的Android平臺(tái)上的第一類語(yǔ)言在五月份。從那之后我就納悶:這是什么語(yǔ)言榕莺?Kotlin已經(jīng)有好幾年了俐芯,并且在2016年2月正式在生產(chǎn)系統(tǒng)上運(yùn)行,語(yǔ)言后的1.0版本钉鸯,為期一年左右泼各。該語(yǔ)言已經(jīng)獲得很多的贊賞和喜愛(ài)。
在這篇文章中我們將涵蓋語(yǔ)法等基本構(gòu)建塊亏拉,在介紹Kotlin第二部分扣蜻,我們將接觸變量,函數(shù)及塘,類莽使,接口和對(duì)象。最后笙僚,在第三部分芳肌,我們來(lái)看一看控制流程的幾個(gè)例子。
1肋层、構(gòu)建過(guò)程
當(dāng)Kotlin在發(fā)展的時(shí)候亿笤,您的構(gòu)建過(guò)程或多或少和舊的java程序類似。既然您已經(jīng)熟悉了這些栋猖,就沒(méi)有必要學(xué)習(xí)新的東西净薛,Gradle/Maven插件:引入Kotlin的構(gòu)建過(guò)程和構(gòu)建工具。
您可以通過(guò)添加Kotlin插件在您的Gradle/Maven中構(gòu)建腳本蒲拉。如何做到這一點(diǎn)以及了解更多信息肃拜,可以從官方文檔Kotlin中找到關(guān)于 Maven /Gradle的更多介紹。
2雌团、Kotlin語(yǔ)法
一位偉人曾經(jīng)說(shuō)過(guò) talk is cheap, show me the code燃领。
貌似在接觸新語(yǔ)言時(shí)第一句學(xué)到的總是以Hello World開(kāi)始的。那我們就從這里開(kāi)始吧锦援。
print("Hello World")
現(xiàn)在猛蔽,我們已經(jīng)看到了不同于java的地方。有一些我們熟悉的東西()表示函數(shù)調(diào)用灵寺,但沒(méi)有分號(hào)去結(jié)尾曼库,不過(guò)看起來(lái)也很整齊。好了替久,下面讓我們開(kāi)始去了解Kotlin吧凉泄。
① Kotlin變量
在Kotlin中聲明變量有一些不同,我們有關(guān)鍵字val和var蚯根,這看起來(lái)很相似后众,但其實(shí)有一個(gè)重要的區(qū)別:
當(dāng)變量被聲明為val時(shí)是不可變的(只讀),你只能給它分配一次值颅拦。變量被聲明為var是可變的蒂誉,可以給它重新分配。
val hello: String = "hello"
val world: String
world = "world"
var helloWorld: String = "Hello"
helloWorld = "Hello World"
注意距帅,變量類型如何定義右锨?用冒號(hào)分隔。這背后還有一個(gè)理由碌秸,編譯器現(xiàn)在可以決定是否要進(jìn)行類型推斷绍移。這意味著Kotlin比Java有著更強(qiáng)大的類型推斷悄窃。實(shí)際上,你也可以不用聲明這些類型編譯器也會(huì)明白你的意思蹂窖。
val hell0 = "hi"
val w0rld = "earth"
只有當(dāng)變量被賦值的時(shí)候轧抗,該變量的類型才能被推斷出來(lái)。
② fun
這是什么樣的功能呢瞬测?由于我們用fun來(lái)聲明它們横媚,它一定很有趣!哈哈月趟。??
// 無(wú)返回值. (也可以這么寫 --> fun sayIt (a: String): Unit)
fun sayIt (a: String) {
println(a)
}
// 有返回值
fun returnIt (returnable: String): String {
return returnable
}
//作為具有推斷返回類型和自動(dòng)返回的單表達(dá)式函數(shù)
fun returnIt2 (turntable: String) =
turntable
類型聲明遵循相同的模式在這里-它排在后面灯蝴。在我們的第一個(gè)我們不返回任何東西,所以我們可以省略到類型孝宗,在這種情況下可以使用Unit穷躁。在第二個(gè)函數(shù)中,我們定義必須返回一個(gè)String碳褒,使用return語(yǔ)句折砸。最后一個(gè)比較令人費(fèi)解,沒(méi)有大括號(hào)沙峻,只是一個(gè)等號(hào)睦授。這意味著fun是一個(gè)表達(dá)式,它可以自動(dòng)返回摔寨。
正如你所看到的去枷,在表達(dá)式的返回類型上是可選的∈歉矗可以省略或者留在原位删顶,什么讓你更方便(經(jīng)驗(yàn)法則:長(zhǎng)的表達(dá)式,把它放在后面淑廊。短的表達(dá)式逗余,它可以省略)。
Kotlin還引入了可選的命名函數(shù)參數(shù)的概念季惩。這是很有用的录粱,特別是如果你的函數(shù)成長(zhǎng)為很多同類型和多種不同參數(shù)的時(shí)候。
fun optFun(isItFun: Boolean = true, whyIsItFun: String = "Because") = if (isItFun) whyIsItFun else "It's not fun"
println(optFun()) // Because
println(optFun(false)) // It’s not fun
println(optFun(whyIsItFun = "It's Summer!")) // It's Summer!
在這個(gè)代碼塊中画拾,我們使用默認(rèn)值來(lái)定義我們的函數(shù)參數(shù)啥繁。當(dāng)我們這么寫的時(shí)候,我們可以直接調(diào)用該函數(shù)的0個(gè)青抛、1個(gè)或者多個(gè)它的參數(shù)旗闽。
③ 類,接口和對(duì)象
與Java一樣,Kotlin也具有類和接口适室。Kotlin團(tuán)隊(duì)決定讓代碼組織更加愉快和語(yǔ)言更加簡(jiǎn)潔嫡意。讓我們先了解一下類。
A亭病、類
class SimpleClass
// 或者 --> class constructor SimpleClassWithConstructor(val chop: String)
class SimpleClassWithConstructor(val chop: String)
在Kotlin中有很多方式可以創(chuàng)建類鹅很。在上面的代碼塊中給了我們提示:
- 命名約定以大寫字母開(kāi)頭
- 沒(méi)有花括號(hào)
- 還有就是在這個(gè)例子中沒(méi)有可見(jiàn)性修改
- 我們?nèi)匀皇褂?strong>class關(guān)鍵字
第二個(gè)例子是相似的,但它有一個(gè)構(gòu)造函數(shù)罪帖。構(gòu)造函數(shù)綁定類的屬性(在大多數(shù)情況下可以不用關(guān)鍵字constructor,只需要添加類的注解或類的可見(jiàn)性)邮屁,另一種方式整袁,使得Kotlin更加簡(jiǎn)潔,當(dāng)我們實(shí)例化這個(gè)類時(shí)需要給chop賦值佑吝。
val lamb = SimpleClassWithConstructor("Hello")
在Kotlin中屬性默認(rèn)是公有的坐昙,所以訪問(wèn)該屬性的最簡(jiǎn)單方法:
println(lamb.chop)
這個(gè)類不具有任何功能,它只是為我們的數(shù)據(jù)提供容器芋忿。我們可以自定義在里面添加fun類功能炸客。在這種情況下,我們需要使用花括號(hào)來(lái)包裹我們的聲明:
class SimpleClassWithConstructor(val chop: String) {
fun sayItMate(): String = chop + ", mate"
}
我們可以在這里添加附加的屬性戈钢,其它類痹仙,額外的構(gòu)造函數(shù)或初始化塊,我們可以給這些單獨(dú)分配可見(jiàn)性殉了。
init在Kotlin中做的事情开仰,就是我們通常在Java構(gòu)造函數(shù)中做的事情。如果你想在類中創(chuàng)建一個(gè)類薪铜,你可以使用inner關(guān)鍵字標(biāo)記它众弓,以便訪問(wèn)外層類的成員。
class Kenny(val celly: String) {
lateinit var wheel: CanadianPerson
val friend: String
init {
friend = "buddy"
}
fun initializeWheel (wheeler: String) {
wheel = CanadianPerson(wheeler)
}
inner class CanadianPerson(val snipe: String)
// 美元符號(hào)使用字符串插值隔箍,并使用該屬性中定義的toString實(shí)現(xiàn)替換$ -prefixed屬性名稱
fun sayItCanadianWay(): String = "${wheel.snipe} $celly, $friend"
}
val d = Kenny("friend")
d.initializeWheel("I’m not")
print(d.sayItCanadianWay()) // I'm not your friend, buddy
我們通過(guò)使用lateinit關(guān)鍵字來(lái)告訴編譯器谓娃,這個(gè)屬性不為空,即使我們不立即初始化它蜒滩,這對(duì)于不在構(gòu)造函數(shù)中初始化屬性很有用滨达。注意,我們的lateinit屬性必須是可變的帮掉。
init相當(dāng)于Java中的構(gòu)造函數(shù)塊弦悉,在那里,我們實(shí)例化類時(shí)蟆炊,我們可以執(zhí)行所需的動(dòng)作稽莉。在這種情況下,我們將一個(gè)String賦值給我們的屬性涩搓。
接下來(lái)污秆,我們有一個(gè)函數(shù)劈猪,最終賦值給我們的lateinit屬性,實(shí)例化一個(gè)內(nèi)部類CanadianPerson良拼,這個(gè)內(nèi)部類只是我們數(shù)據(jù)的載體战得。
最后,我們將調(diào)用一個(gè)函數(shù)庸推,這個(gè)函數(shù)將返回一個(gè)String常侦,它使用字符串插值將它們解析并展示出來(lái)。
當(dāng)向類添加其他構(gòu)造函數(shù)時(shí)贬媒,我們需要調(diào)用它們?cè)嫉臉?gòu)造函數(shù)聋亡。
class DoubleTrouble(val str: String){
constructor(lamb: SimpleClassWithConstructor): this(lamb.chop)
}
我們?cè)陬愔刑砑右恍┖?jiǎn)單的功能,除了保存數(shù)據(jù)什么都不做际乘。
對(duì)于這些類型的數(shù)據(jù)傳輸對(duì)象坡倔。Kotlin引入了一個(gè)關(guān)鍵字來(lái)定義它們:data class。它不同于標(biāo)準(zhǔn)的類脖含,一個(gè)data class自動(dòng)生成equals罪塔,hashcode,toString和copy功能养葵。前三個(gè)對(duì)Java開(kāi)發(fā)者來(lái)說(shuō)是比較熟悉的征堪,第四個(gè)是個(gè)很好的補(bǔ)充,可以幫助我們從只讀數(shù)據(jù)類創(chuàng)建類似的對(duì)象港柜。該copy功能可以這么用:
data class DataClass(val str: String, val num: Int)
val daata = DataClass("Hello", 3)
val peeta = daata.copy(str = "Goodbye")
在這種情況下请契,我們的peeta包含了num=3和str=“Goodbye”。
我們也可以去獲取component數(shù)據(jù)類對(duì)象夏醉,這些組件函數(shù)通過(guò)解構(gòu)來(lái)訪問(wèn)數(shù)據(jù)類中數(shù)據(jù)的一種方式爽锥。這有利于通過(guò)簡(jiǎn)單的一行調(diào)用來(lái)獲取數(shù)據(jù)類中的單個(gè)屬性。
val (str, num) = peeta
有了這個(gè)技巧畔柔,我們的變量str和num的值分別為"Goodbye"和3氯夷。請(qǐng)注意,解構(gòu)變量的順序取決于數(shù)據(jù)類中屬性的順序靶擦;這些名字根本不重要腮考。
另外還有兩個(gè)頂級(jí)結(jié)構(gòu)interface和objects。
b玄捕、接口
Kotlin中接口與Java中沒(méi)有什么不同踩蔚,
interface Sayer {
val value: String
fun sayIt(): String
}
class SayerClass: Sayer{
override val value: String = "Hello"
override fun sayIt(): String = "$value, world"
}
println(SayerClass().sayIt()) // Hello, world
如您所見(jiàn),這與Java非常相似枚粘,像Java8一樣馅闽,Kotlin也可以在接口中提供默認(rèn)實(shí)現(xiàn),我們可以利用這個(gè)特性實(shí)現(xiàn)上面一樣的效果。
interface Sayer {
val value: String
fun sayIt(): String {
return "$value, world"
}
}
使用這個(gè)我們不必重新實(shí)現(xiàn)類中的函數(shù)福也。請(qǐng)注意局骤,override關(guān)鍵字在Kotlin中是強(qiáng)制性的。
c暴凑、對(duì)象
object SingletonClass{
fun sayIt(): String = "Hello world"
}
class CompaniedClass(val str: String){
companion object Printer{
fun sayIt(): String = "Hello world"
}
}
這是什么呢峦甩?你可以使用object關(guān)鍵字創(chuàng)建SingletonClass的單例。
SingletonClass.sayIt() // Hello world
Companied對(duì)象是略有不同的现喳,它在一個(gè)類中定義凯傲,它仍然是一個(gè)單例,它可以使用包裝類的名稱來(lái)訪問(wèn)嗦篱。
CompaniedClass.sayIt() // Hello world
4泣洞、控制流程(if,when默色,for)
a、if
if在Kotlin中的語(yǔ)句或多或少與Java類似狮腿,下面我們來(lái)看一下它們的不同:
val three = 4
if (three != 3) {
println("Liar!")
} else{
println("Good job")
}
這看起來(lái)與Java完全相同腿宰。但是也略有不同。
val three = 4
val goodOrNot = if(three != 3) {
"Liar!"
} else{
"Good job"
}
println(goodOrNot) // Liar!
如果Kotlin語(yǔ)句實(shí)際上是表達(dá)式缘厢,它返回它們塊中的最后一個(gè)值吃度,
b、when
我們常用的switch-case與三元運(yùn)算符有著同樣的命運(yùn)贴硫,它已被Kotlin的when所取代椿每。
when (three) {
3 -> print("three is three")
2 -> print("three is two?!?")
else -> print("I don't know what's going on anymore")
}
正如你所看到的,else替代了default英遭,->替換了:字符间护,關(guān)鍵字break也不再需要,因?yàn)?strong>when表達(dá)式將在第一個(gè)為真時(shí)停止挖诸。這些when表達(dá)式有一些有趣的地方汁尺,它們可以使用任何類型的表達(dá)式進(jìn)行判斷,許多情況下多律,可以捆綁在一起痴突,而對(duì)于數(shù)值,可以判斷它們的范圍狼荞。
when (three) {
3 -> print("three is three")
1,2 -> print("three is two or one?!?")
in 4..10 -> print("What? Three can't be between 4 and 10!")
else -> print("I don't know what's going on anymore")
}
同樣的辽装,我們也可以使用when來(lái)返回具體值。雖然這看起來(lái)有點(diǎn)像if表達(dá)式相味。
val three = 4
val goodOrNot = when {
three != 3 -> "Liar!"
else -> "Good job"
}
println(goodOrNot) // Liar!
c拾积、for
for循環(huán)相對(duì)于Java有挺大的改動(dòng)。
for (i in 1..10) {
print(i)
} // 12345678910
for (i in 1..10 step 2) {
print(i)
} // 13579
val lst = listOf(1,2,3)
for (i in lst){
print(i)
} // 123
在第一個(gè)例子中我們使用in關(guān)鍵從range中通過(guò)..來(lái)分配i的值。第二個(gè)例子中使用step關(guān)鍵字殷勘,表示我們要從這個(gè)范圍中取其它值此再。第三個(gè)例子循環(huán)列表,將listof值打印出來(lái)玲销。
總結(jié)
以上就是Kotlin語(yǔ)言的基本組成部分输拇,有了這些你就可以使用Kotlin了。希望在看完這篇文章后贤斜,你對(duì)Kotlin會(huì)有自己的看法策吠,在下一章中我們將介紹null safety, lambdas, collections, and types以及Kotlin語(yǔ)言中幾個(gè)便利的功能。