kotlin基礎(chǔ)語法

每種編程語言都有一定的語法笆载、語義和執(zhí)行順序(同步)旷档,學習一種新語言也都是從這三者出發(fā),下面我們就只針對kotlin的語法來做簡單的介紹梁丘。

Kotlin有自己的特性不該被Java的思維所束縛燕偶。

  1. 基本語法準則:
    在Kotlin中常量用 val 聲明喝噪,變量用 var 聲明;
    關(guān)鍵字在前面指么,類型以冒號 :隔開在后面酝惧,也可以省略直接賦值榴鼎;
    類型后帶問號 ? 表示可為空類型(默認空類型安全);
    常量 val 延遲加載 by lazy{} 晚唇;
    默認是線程安全的巫财,關(guān)閉線程安全 lazy(LazyThreadSafetyMode.NONE){} ;
    變量 var 延遲加載 lateinit ;
    內(nèi)部類和參數(shù)默認為public哩陕,而在Java中為private
    類默認為不可繼承(final)平项,想要可被繼承要聲明為 open 或 abstract
    取消了static關(guān)鍵字,靜態(tài)方法和參數(shù)統(tǒng)一寫在 companion object 塊
    internal模塊內(nèi)可見悍及,inner內(nèi)部類
//常量數(shù)組int[][][] arrs = new int[3][2][1];
val arrs = Array(3) { Array(2) { IntArray(1) } }
internal var name: String? = null//類型后帶問號 ? 表示可為空類型(默認空安全)
internal var age: Int = 0//internal模塊內(nèi)可見闽瓢,inner內(nèi)部類
//當我們只有單個構(gòu)造器時,我們需要在從父類繼承下來的構(gòu)造器中指定需要的參數(shù)心赶。這是用來替換Java中的super調(diào)用的扣讼。
open class Animal(name: String)
class Person(name: String, surname: String) : Animal(name)

kotlin是空類型安全的,所有變量默認為"not null"缨叫,必須顯式在類型后添加椭符?修飾符才可賦值為null。

var notNullArtist: Artist = null//編譯不通過耻姥,因為notNullArtist不能為null
var artist: Artist? = null//編譯通過
artist.print()//編譯不通過销钝,因為artist可能為空
/** Kotlin進行空判斷處理,有兩種處理方式:
     * 1. 拋出空異常咏闪,字段后加 !! 
     * 2. 不做處理直接跳過曙搬,字段后加 ?
     */
artist?.print()//編譯通過摔吏,做了非空判斷,只有當artist鸽嫂!=null時才調(diào)用print()
artist!!.print()//這種用法只有在確認artist不為null時才能調(diào)用,否則拋出空指針異常
val name = artist?.name?:"empty"http://當artist為null時可以指定一個默認值
  1. 條件語句
    if...else 正常使用征讲,不過移除了 switch 用更強大的 when 替代据某,when子式可以是各種返回Boolean的表達式
val x = 7
when (x) {
  in 1..5 -> print("x is in the range")
  in validNumbers -> print("x is valid")
  !in 10..20 -> print("x is outside the range")
  else -> print("none of the above")
}

kotlin盡可能多的使用when

  1. 循環(huán)語句
    while 和 do...while 同Java并無區(qū)別, for 則有很大改變并多出了幾個變種
fun main(args: Array<String>) {
    var list = ArrayList<String>()
    add(list)
    list.forEachIndexed { i, s ->
    print(list[i])
    print(s)
    }
    println()
    //如果沒有指定函數(shù)的返回值诗箍,它就會返回Unit癣籽,與Java中的void類似,但是Unit是一個真正的對象滤祖。當然也可以指定任何其它的返回類型:
    list.forEachIndexed(object :(Int,String) -> Unit{
    override fun invoke(i: Int, s: String) {
        print(list[i])
        print(s)
    }
})
}
//遞增for (int i = 0; i < list.size(); i++)
for (i in list.indices) {
   print(list[i])
}
//遞增for (int i = 2; i < list.size(); i++)
for (i in 2..list.size-1) {
   print(list[i])
}
//遞減for (int i = list.size(); i >= 0; i--)
for (i in list.size downTo 0) {
    print(list[i])
}
//操作列表內(nèi)的對象
for (item in list) {
    print(item)
}
//加強版
for((i,item) in list.withIndex()){
    print(list[i])
    print(item)
}
//變種版
list.forEach {
    print(it)
}

list.forEachIndexed { i, s ->
    print(list[i])
    print(s)
}

list.forEachIndexed(object :(Int,String) -> Unit{
    override fun invoke(i: Int, s: String) {
        print(list[i])
        print(s)
    }
})
fun add(list:MutableList<String>) {
        for (i in 0..4) {
            list.add(i.toString() + "")
        }
    }

冒號使用
??在Kotlin中冒號 : 用萬能來稱呼絕不為過筷狼。常量變量的類型聲明,函數(shù)的返回值匠童,類的繼承都需要它

除此之外還有一個特別的地方也需要它埂材,使用Java類的時候。Kotlin最終會還是編譯成Java字節(jié)碼汤求,使用到Java類是必然的俏险,在Kotlin語法如下
val intent = Intent(this, MainActivity::class.java)

指定上下文的@

除了冒號另一個重要符號 @ 严拒,java代碼中經(jīng)常用到內(nèi)部類和匿名內(nèi)部類,有時我們不能確定this指代的上下文竖独,Java可以使用XXX.this指代具體上下文裤唠,在kotlin中的做法是this@XXX

class User {
    inner class State{
        fun getUser(): User{
            //返回User
            return this@User
        }
        fun getState(): State{
            //返回State
            return this@State
        }
    }
}

kotlin的特色

Java的 getter/setter 方法自動轉(zhuǎn)換成屬性,對應(yīng)到Kotlin屬性的調(diào)用

public class User {
    private String name;
    private String age;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getAge() {
        return age;
    }

    public void setAge(String age) {
        this.age = age;
    }
}

對應(yīng)的kotlin

val user = User()
//賦值
user.name = "tutu"
user.age = "23"
//取值
val name = user.name
val age = user.age

class User {
    var name: String? = null
    var age: String? = null
}

有時 getter/setter 方法比較復(fù)雜莹痢,這就需要自定義 getter/setter 了种蘸,實現(xiàn)一個Java中常用的單例,這里只為了展示竞膳,單例在Kotlin有更簡單的方法實現(xiàn)劈彪,只要在 package 級別創(chuàng)建一個 object 即可

class User {
    companion object {//靜態(tài)方法和參數(shù)統(tǒng)一寫在 companion object 塊
         //volatile不保證原子操作,所以顶猜,很容易讀到臟數(shù)據(jù)沧奴。在兩個或者更多的線程訪問的成員變量上使用volatile
        @Volatile var instance: User? = null
            get() {
                if (field == null) {
                    synchronized(User::class.java) {
                        if (field == null)
                            field = User()
                    }
                }
                return field
            }
    }

    var name: String? = null
    var age: String? = null
}

自定義 getter/setter 重點在 field ,跟我們熟悉所Java的 this 指代當前類一樣长窄, field 指代當前參數(shù)滔吠,直接使用參數(shù)名 instance 代替不會報錯但單例就沒效果了

字符串問題

在Java中拼接字符串的代碼可讀性都很差,在Kotlin字符串拼接變得非常簡潔挠日,只需用 $ 后面加上參數(shù)名疮绷,復(fù)雜的參數(shù)要加上 {}

 val pair = Pair(1, "one")
 val (num, name) = pair
 println("num = $num, name = $name")

輸出num = 1, name = one

Java8新特性lambda的支持

lambda需要一個函數(shù),但是又不想費神去命名一個函數(shù)的場合下使用嚣潜,也就是指匿名函數(shù)冬骚。使用功能接口,把接口名懂算、方法名和參數(shù)類型省掉不寫再加個 -> 罷了只冻。

使用Java開發(fā)Android時,處理監(jiān)聽回調(diào)是常見的事计技,kotlin可以直接編寫監(jiān)聽回調(diào)而不用再通過匿名對象傳遞onClick方法喜德,這個特性被稱為Lambda表達式

view.setOnclickListener({
      Toast.makeText(this, "Hello World!", Toast.LENGTH_LONG).show()
})

擴展函數(shù)

可以為任何已經(jīng)存在的類添加新函數(shù),相比傳統(tǒng)工具類垮媒,擴展函數(shù)更具有可讀性舍悯。

//為Fragment添加擴展函數(shù)
fun Fragment.toast(message: CharSequence, duration: Int = Toast.LENGTH_LONG){
      Toast.makeText(getActivity(), message, duration).show()
}

調(diào)用時直接調(diào)用fragment.toast("Hello World!")或fragment.toast("Hello World!", 2000)

Kotlin中的參數(shù)與Java中有些不同。如你所見睡雇,我們先寫參數(shù)的名字再寫它的類型萌衬。上面調(diào)用的第二個參數(shù)(length)指定了一個默認值。這意味著你調(diào)用的時候可以傳入第二個值或者不傳它抱,這樣可以避免你需要的重載函數(shù)秕豫。

函數(shù)式支持(lambda),函數(shù)是一級公民

集合操作

??list轉(zhuǎn)map(associateBy)

??場景:訂單列表轉(zhuǎn)換成以 id為key 的訂單map

val mainOrders = orderDao!!.queryUserOrder(param)
val orderMap = mainOrders.associateBy { it.id }.toMap()

??map的key或者value轉(zhuǎn)換

??假如一個map的key是String抗愁,需要轉(zhuǎn)換成Long馁蒂;或者map的value是一個對象呵晚,要轉(zhuǎn)成另一個對象。按照標準Java寫法沫屡,可以要new一個新的map饵隙,然后循環(huán)老的map,在kotlin中沮脖,一行代碼搞定

val map = mutableMapOf(1 to 1, 2 to 2)
val newMap = map.mapKeys { "key_${it.key}" }.mapValues { "value_${it.value}" }
println(newMap)
//打印結(jié)果 {key_1=value_1, key_2=value_2}
val pair = Pair("ss","sg")
 val map = mapOf(pair)
val map1=map.mapKeys { entry -> "${entry.value}!"  }
    for((key,value) in map1){
        println("map1:key=$key")
        println("map1:value=$value")
    }
        val map2 =map.mapKeys { (key, value) -> "$value"  }
    for((key,value) in map2){
        println("map2:key=$key")
        println("map2:value=$value")
    }
        val map3=map.mapValues { entry -> "${entry.value}!" }
    for((key,value) in map3){
        println("map3:key=$key")
        println("map3:value=$value")
    }
        val map4=map.mapValues { (key, value) -> "$value" }
    for((key,value) in map4){
        println("map4:key=$key")
        println("map4:value=$value")
    }
打印結(jié)果:
map1:key=sg!
map1:value=sg
map2:key=sg
map2:value=sg
map3:key=ss
map3:value=sg!
map4:key=ss
map4:value=sg

參考文獻
??Kotlin for android Developers
??kotlin 腳本練習

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末金矛,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子勺届,更是在濱河造成了極大的恐慌驶俊,老刑警劉巖,帶你破解...
    沈念sama閱讀 211,290評論 6 491
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件免姿,死亡現(xiàn)場離奇詭異饼酿,居然都是意外死亡,警方通過查閱死者的電腦和手機胚膊,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,107評論 2 385
  • 文/潘曉璐 我一進店門故俐,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人紊婉,你說我怎么就攤上這事药版。” “怎么了喻犁?”我有些...
    開封第一講書人閱讀 156,872評論 0 347
  • 文/不壞的土叔 我叫張陵槽片,是天一觀的道長。 經(jīng)常有香客問我肢础,道長还栓,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,415評論 1 283
  • 正文 為了忘掉前任乔妈,我火速辦了婚禮蝙云,結(jié)果婚禮上氓皱,老公的妹妹穿的比我還像新娘路召。我一直安慰自己,他們只是感情好波材,可當我...
    茶點故事閱讀 65,453評論 6 385
  • 文/花漫 我一把揭開白布股淡。 她就那樣靜靜地躺著,像睡著了一般廷区。 火紅的嫁衣襯著肌膚如雪唯灵。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,784評論 1 290
  • 那天隙轻,我揣著相機與錄音埠帕,去河邊找鬼垢揩。 笑死,一個胖子當著我的面吹牛敛瓷,可吹牛的內(nèi)容都是我干的叁巨。 我是一名探鬼主播,決...
    沈念sama閱讀 38,927評論 3 406
  • 文/蒼蘭香墨 我猛地睜開眼呐籽,長吁一口氣:“原來是場噩夢啊……” “哼锋勺!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起狡蝶,我...
    開封第一講書人閱讀 37,691評論 0 266
  • 序言:老撾萬榮一對情侶失蹤庶橱,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后贪惹,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體苏章,經(jīng)...
    沈念sama閱讀 44,137評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,472評論 2 326
  • 正文 我和宋清朗相戀三年奏瞬,在試婚紗的時候發(fā)現(xiàn)自己被綠了布近。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,622評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡丝格,死狀恐怖撑瞧,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情显蝌,我是刑警寧澤预伺,帶...
    沈念sama閱讀 34,289評論 4 329
  • 正文 年R本政府宣布,位于F島的核電站曼尊,受9級特大地震影響酬诀,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜骆撇,卻給世界環(huán)境...
    茶點故事閱讀 39,887評論 3 312
  • 文/蒙蒙 一瞒御、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧神郊,春花似錦肴裙、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,741評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至夕晓,卻和暖如春宛乃,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,977評論 1 265
  • 我被黑心中介騙來泰國打工征炼, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留析既,地道東北人。 一個月前我還...
    沈念sama閱讀 46,316評論 2 360
  • 正文 我出身青樓谆奥,卻偏偏與公主長得像渡贾,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子雄右,可洞房花燭夜當晚...
    茶點故事閱讀 43,490評論 2 348

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

  • 前言 人生苦多空骚,快來 Kotlin ,快速學習Kotlin擂仍! 什么是Kotlin囤屹? Kotlin 是種靜態(tài)類型編程...
    任半生囂狂閱讀 26,163評論 9 118
  • 一、常量與變量(val,var) 1.什么是常量逢渔? 1 .val = value ,值類型;2.類似Java的fi...
    Serenity那年閱讀 531評論 0 7
  • 1.函數(shù) (1)Main函數(shù)默認是Unit返回類型肋坚,可以定義其他返回類型:Int (2)直接聲明一個函數(shù),給出返回...
    賈里閱讀 495評論 0 0
  • 基本類型 在 Kotlin 中肃廓,所有東西都是對象智厌,在這個意義上講我們可以在任何變量上調(diào)用成員函數(shù)和屬性。 一些類型...
    Whyn閱讀 428評論 0 0
  • 青青诚卸,是一個即將畢業(yè)的求職狗! 一開始绘迁,他熱血沸騰合溺,信心滿滿!但四處碰壁缀台!后來棠赛,覺得是個工作就行!再后來呢膛腐?他的結(jié)...
    這個糖不太甜閱讀 382評論 0 0