隨著2017年google的I/O大會(huì)的結(jié)束,kotlin(科特林)語(yǔ)言已經(jīng)炒的非常活了;基本上現(xiàn)在各大網(wǎng)站上都在推測(cè)未來(lái)用kotelin語(yǔ)言開(kāi)發(fā)的可能性會(huì)非常大;所以我也想跟大家一起分享一些這門語(yǔ)言的語(yǔ)法
聲明一個(gè)對(duì)象
kotlin的一切變量都是對(duì)象,所以沒(méi)有Java那樣基本類型。
kotlin聲明對(duì)象有兩種類型:
1.可變對(duì)象
var x = 5? ? ? ? ? ? ? ? ? ? ? // 類型推斷為`Int`型
var b: String = "Hello"? ? ? ? // String型
2.不可變對(duì)象,kotlin沒(méi)有final關(guān)鍵字,而且不存在靜態(tài)變量
例如:val x=5 ?//不可變int型變量
x +=1 ? ? //這樣寫編譯器會(huì)報(bào)錯(cuò)
從上面代碼碎片段可以看出,kotlin不需要再每一行結(jié)束加分號(hào)。
區(qū)分非空類型
在kotlin中,nullable對(duì)象和nullable對(duì)象是嚴(yán)格區(qū)分的,甚至在編譯期解決了不少潛在的空指針問(wèn)題;聲明變量時(shí);對(duì)變量的類型都是默認(rèn)非空的,如果要允許變量為空,必須在定義類型后面加上一個(gè)問(wèn)號(hào)?
例如: ?var a: String ="hello" //a字符串不可為空
var ?b: String ?= "hello" ? ? //b字符串可以為空
a=null ?//編譯器會(huì)報(bào)錯(cuò)
b =null ?//ok通過(guò)
而且,在對(duì)有可能為空的對(duì)象進(jìn)行操作時(shí),編譯器會(huì)提示警告warning,同時(shí),kotlin提供類似Ruby和coffeeScript的語(yǔ)法糖:
var b: String ?="hello"?
b?.length() ? ? ?//這樣寫的好處是,如果b不為空對(duì)象,則取b得長(zhǎng)度,用于if判斷
智能類型轉(zhuǎn)換
在kotlin中,進(jìn)行強(qiáng)制類型轉(zhuǎn)換可以使用as關(guān)鍵字,但有可能會(huì)拋出異常:
if(c ?is ?String){//kotlin使用is關(guān)鍵字判斷對(duì)象
c.length()
}
在上面的例子中,如果c是一個(gè)String對(duì)象,則在if塊中,可以直接使用String的方法,編譯器會(huì)智能的幫你識(shí)別出c在if-blcok里面是一個(gè)String對(duì)象的。
流程控制
if?
kotlin的if表達(dá)式與java的一樣,只是kotlin中沒(méi)有三目表達(dá)式,所以if 和 else 可以這樣寫:
val a=1?
val b=2
val max = if (a>b) a ?else b ? ? //類似JAVA的 :int max =a>b ?a:b;
when
kotlin用when表達(dá)式來(lái)替代java的Switch:
when(x){
print(”x==1“)
print (”x==2“)
else{
print(”x is neither 1 nor 2“)
}
}
for
kotlin的for表達(dá)式和Java的foreach一致
for(i ?in array.indices)
print(array[i])
while
while表達(dá)式和Java的一樣
white(x>0){
x--
}
do{val ?y=retrieveData()
}while(y !=null) ? //與Java不同
函數(shù)
與Java不同的是,kotlin的函數(shù)是一等成員,不需要再類內(nèi)定義,可以脫離類的存在的,而且kotlin是不支持類靜態(tài)方法的。
fun ?hello():Unit{
print(”hello“)
}
fun ?add(a: Int,b : Int): Int{
return ?a+b
}
kotlin沒(méi)有void關(guān)鍵字,函數(shù)都是要返回對(duì)象的,所以如果沒(méi)東西返回的時(shí)候,函數(shù)后要聲明Unit類型(M10版本之后就默認(rèn)不要用了)
如果函數(shù)比較簡(jiǎn)單可以放在一行的話,甚至可以這樣:
fun ?add(a: Int, b : Int) =a+b
這樣函數(shù)默認(rèn)返回最后計(jì)算結(jié)果。
擴(kuò)展類的函數(shù)
通常開(kāi)發(fā)中,我們往往要對(duì)提供的API類進(jìn)行擴(kuò)展,增加一些方法,如果是JAVA的話,要想這樣做,則聲明一個(gè)繼承該API的子類。kotlin采取了C#的辦法,可以直接擴(kuò)展類的方法:
fun ?Fragment.findViewById(id : Int) = this.getView.findViewById(id)
從而不需要衍生出一堆子類或者輔助工具類。如果擴(kuò)展類里面本來(lái)就有這個(gè)同名方法,但類對(duì)象調(diào)用這個(gè)同名方法的時(shí)會(huì)出現(xiàn)什么情況呢?答案是:如果類里面就有這個(gè)方法,kotlin就會(huì)調(diào)用原來(lái)的方法,而不調(diào)用擴(kuò)展方法。
利用這個(gè)特性,kotlin的擴(kuò)展函數(shù)就可以提供舊版本api兼容了。比如自android API 16之后,View提供了setBackground方法,原來(lái)的setBackgroundDrawable則被標(biāo)記過(guò)時(shí)了,如果要在舊Android手機(jī)上使用該Api,我們可以這樣寫:
fun View.setBackground(background : Drawable) =this.setBackgrountDrawable(backgrount:)
這樣,在舊的手機(jī)上,APP就可以用自定義的setBackground的Wrapper,而在高版本的手機(jī)上APP會(huì)調(diào)用原生的setBackground方法。
Lambda表達(dá)式
Kotlin引入了Lambda表達(dá)式,而且Kotlin的Lambda表達(dá)式支持Android平臺(tái):
view.setonClickListener({ toast("Hello world!")})
這樣簡(jiǎn)化了寫監(jiān)聽(tīng)器對(duì)象了
類
kotlin的類是這樣聲明的:
class ?User(val ? id : Int ?,val name :String){//只有一個(gè)構(gòu)造方法,可以這樣聲明
init{
print("constructor ?$id : $name")
}
}
val ? ?user =User(1,"aaaaa");
從上面代碼片段可以看出,Kotlin在調(diào)用構(gòu)建方法時(shí),會(huì)先調(diào)用init代碼塊內(nèi)的代碼,而且構(gòu)建類對(duì)象的時(shí)候,是不需要new關(guān)鍵字的。
那么,如果有多個(gè)構(gòu)造方法怎么辦呢?在Kotlin的類內(nèi),構(gòu)造方法名都是規(guī)定為constructor的:
class User { // 只有一個(gè)構(gòu)造方法是,可以這樣聲明
var _id: Int = 0
var _name: String = ""
constructor(id: Int, name: String) {
_id = id
_name = name
}
constructor(name: String): this(0, name) {
}
init {
print("Constructor $id : $name")
}
// Nothing
}
val user = User(1, "AAAAAA")
Kotlin的類默認(rèn)是final的,也就是不可繼承,如果類可繼承,則要帶有open關(guān)鍵字聲明:
open class User(val id: Int, val name: String) {
// Nothing
}
虛類Kotlin與Java一樣,都是用abstract關(guān)鍵字聲明,當(dāng)有abstract關(guān)鍵字的時(shí)候,就不需要帶有open了:
abstract class User() {
// Nothing
}
Getter和Setter
Kotlin的Setter和Getter編碼風(fēng)格與C#類似:
class User{
private var ?_id :Int?
var ?id: Int?
get() =_id
set(value){
_id =value
}}
Data Class
Kotlin的類可以申明data關(guān)鍵字,相當(dāng)與專用與存儲(chǔ)數(shù)據(jù)的Pojo類:
data class User(val id: Int = 0, val name: String = "")
而且Data Class可以進(jìn)行這樣的操作:
val jane = User(1, "Jane")
val (id, name) = jane
println("$name id is $id")
內(nèi)部類
Kotlin同樣支持內(nèi)部類,但是Kotlin的內(nèi)部類是默認(rèn)不帶有外部類的引用的,也就是說(shuō)默認(rèn)的Kotlin內(nèi)部類都是靜態(tài)的。要想內(nèi)部類帶有外部類的引用,要在內(nèi)部類聲明上加入inner關(guān)鍵字:
class User(val id:Int, val name: String) {
inner class School(val name: String) {
// Nothing
}
}
接口
Kotlin的接口和Java的類似,而且還支持Java 8的默認(rèn)方法:
interface MyInterface {
fun bar()
fun foo() {
print("foo")
}
}
android工程中配置kotlin
在Android項(xiàng)目中使用Kotlin非常簡(jiǎn)單,而且Kotlin可以和Java混編,所以完全部分功能用Kotlin開(kāi)發(fā),部分功能用Java開(kāi)發(fā)
首先,確保Android Studio或者Intellij Idea安裝了Kotlin插件。
然后,在項(xiàng)目module的build.gradle上聲明:
apply plugin: 'kotlin-android
接著,添加kotlin依賴:
dependencies {
compile 'org.jetbrains.kotlin:kotlin-stdlib:0.1-SNAPSHOT'
}
最后,添加kotlin源碼文件夾即可:
android {
...
sourceSets {
main.java.srcDirs += 'src/main/kotlin'
}
}
以上就可以了!!!