歡迎光臨
每天分享高質量文章

使用 Kotlin 做開發一個月後的感想

作者:業松

鏈接:https://www.jianshu.com/p/5961116ddba6

談 kotlin之前

有一類程式員,自己根本沒體驗過的東西,看了幾篇嘩眾取寵的博文自己也來嘲諷,我稱之為雲程式員。就比如 Kotlin,有人蹭熱度寫幾篇類似“我為什麼從 kotlin 又回到java”的博文,就把 kotlin 一通批判。有空看看這些蹭熱度博文為啥不看看Android Developer 官網所有示例代碼都是 kotlin 版本在前,java 版本在後呢?

爭論語言、框架的優劣是沒有意義的。很多程式員總是對自己一直使用的語言、框架大肆吹捧而對其他語言、框架各種貶低,很明顯這樣的程式員太狹隘了。Java確實常年排名第一,其他語言就沒有意義了嗎?當然不是,即使是批判,你也得自己真的體驗過了才有資格。這可不是你行你上的翻版,畢竟瞭解一門新語言對一個真正程式員老說是很輕鬆的事。

簡潔的語法

Kotlin給我的感覺就是它就是針對Java里所有的痛點來做改變的,比如語法繁瑣,煩人的空指標,缺少函式式編程支持(Java8雖然支持Lambda運算式但還遠遠不夠)等等。不像它的孿生兄弟Scala那樣奔放,Kotlin給我的感受是聰明又剋制,對Java程式員來說半天就足夠上手開幹了,不像Scala門檻那麼高。

Java語言是我所接觸過語言中語法最繁瑣的(有更繁瑣的請告知),這種繁瑣在main函式就可以體現,而且Java可能也是唯一一個幾乎沒法不用IDE的語言。其他語言脫離了IDE的語法警告和代碼生成模版也勉強能寫一寫,Java代碼你沒有試試看?

但是Java的語法之嚴謹和繁瑣恰恰是Java如此流行的原因。沒寫過Java的人可能沒法理解這句話。人們對於Java嚴苛的語法還不夠滿意,還要再加上 check-style,findbugs以及各種XXX公司Java代碼規範等各種條條框框,最終得到的結果是所有Java程式員寫出來的代碼都能互相看懂。即使是剛畢業不久的Java程式員,只要熟悉Java面向物件語法,幾乎不存在看不懂其他Java代碼的情況(業務看不懂除外)。這樣保證了Java程式員的代碼下限非常之高,能夠保證大型專案的成功。

好像扯 Java 扯的有點多了。接觸 Kotlin 之後會發現,kotlin 在盡可能保持和 Java一樣的語法嚴苛性的情況下,大幅度地精簡了 Java 代碼,寫起來非常之爽。

//快速創建一個Bean類
data class Person(val id: Long, var name: String, var age: Int)

fun main() {
    // 創建實體
    val zhangsan = Person(0L"zhangsan"23)
    // set/get方法
    zhangsan.age = 24
    val name = zhangsan.name

    //copy方法
    val lisi = zhangsan.copy(id = 1, name = "lisi")
    //預設生成的tostring和equals/hashcode方法,可重寫
    zhangsan.toString()
    zhangsan.hashCode()
    var isEqual = zhangsan.equals(lisi)
}

簡潔的語法無處不在,比如上面的Bean類如果用java來寫至少要多好幾倍的代碼。單例樣式只需要把class換成object即可。這些雖然用Java的IDE的各種模版生成工具一樣可以秒生成,但是還是kotlin寫起來更舒服一些。

我想強調的是,Kotlin並不是無腦地利用語法糖和新關鍵字來精簡語法,我們可以很清晰地感受到Kotlin在設計過程中盡可能地保證它盡可能的語法嚴苛性。

空指標

Java 的空指標異常被稱之為 “Billion Dollar Mistake”。在上家公司的時候為了避免空指標異常,代碼規範要求幾乎所有的物件都要進行判空操作,那種嵌套很深的json物件,判空起來真的是又臭又長。

val name: String?
//這裡要吐槽下為啥kotlin沒有三目運算子?
name = if(Random.nextBoolean()) "Ann" else null
//加上?則只在name不為null的時候會呼叫,得到的len1型別也是有問號的,即Int?
val len1 = name?.length
//這種寫法是如果為空給一個預設值,得到的len2型別為Int,不帶問號
val len2 = name?.length?:0
//加上雙感嘆號其實就是java什麼都不加的寫法了,如果為null會報空指標異常
val len3 = name!!.length

上面的代碼解釋了三種對可能為空的物件的處理。其實我把 Kotlin 對空指標的處理歸類為給所有物件加了個範型——符號?,對於帶?的物件則表明它可能為空,你不處理直接使用的話不讓編譯,也就是把空指標儘量扼殺在編譯期間。這個想法真的是簡單又巧妙。很多人一聽 Kotlin 就說沒有空指標了,但是沒用過的話並不知道怎麼實現的。現在再有面試官問你,知道怎麼回答了吧?

函式式編程

fun AppCompatActivity.setupActionBar(@IdRes toolbarId: Int, action: ActionBar.() -> Unit) {
    val toolbar = findViewById(toolbarId)
    setSupportActionBar(toolbar)
    supportActionBar?.run {
        //執行引數中的函式,這樣用戶在呼叫該方法的時候更加靈活
        action()
    }
    toolbar.setNavigationOnClickListener {
        Log.d("AppCompatActivity""finish")
        finish()
    }
}

//------------------------分割線-----------------------------
//類似的單方法接口現在只需要寫一個閉包就行了
binding.aliPayIcon.setOnClickListener {
    Log.d("example", it.contentDescription.toString())
}

//擴展函式let,只有在物件不為空的時候會呼叫,相當於做了判空
binding.let {
    it.setLifecycleOwner(this@WithdrawActivity)
    it.viewModel = vm
}

//擴展函式apply, 在閉包內可直接呼叫物件的方法屬性,有個好處就是可以直接操作物件不需要先生成變數
vm.accountName.apply {
    this.value = "aaaa"
    Log.d("example"this.value?.toString() + ":" + this.hashCode())
}

//還有其他基礎擴展函式run, with, also等等,可以看看這篇博客的介紹:https://www.jianshu.com/p/28ce69d58fea

函式式編程對很多Java程式員來說是很陌生的。儘管我不想黑,但是Java真的強到讓很多Java程式員只會Java一門語言,並且基本上Java8以上的版本也沒接觸過。而除了Java(Java8以下)我還真不知道哪門語言不支持函式式編程。

幾乎所有語言都支持函式式編程,因此會靈活使用函式式編程真的挺重要。Java不支持是因為函式式編程相對要難一點,不支持函式式編程反而讓Java代碼的下限更高。除了難度大一點,函式式編程最令人不爽的就是閱讀性差(可能比較依賴寫代碼的人的水平),我看Java框架原始碼基本都很順暢,但是看JavaScript框架簡直懵逼。我現在的水平看Kotlin函式式代碼也費勁,但是kotlin畢竟是強型別語言,函式的引數和傳回值型別固定的話,認真讀還是不難讀懂的。

扯遠了,函式式編程的好處就是代碼靈活度加倍提高,可以寫出各種秀操作的代碼,顯然這也是一把雙刃劍。不過隨著函式式編程越來越流行,大家的水平越來越高,寫出來的函式式代碼勢必越來越好。

可以說Java程式員學習Kotlin唯一的難點就是函式式編程了,當然如果你本身就有函式式編程經驗這點也不是事。如果沒有的話就要好好學習參悟下函式式編程了,這是一個相對漫長的過程。在熟練掌握之前,不使用函式式編程也一樣可以寫 Kotlin。

結語

總的來說我對 Kotlin 的評價總體是正面的。不過有些人的腦迴路不正常,我還是想說一下:說 Kotlin 好,有優點,馬上又有人驚呼Java要被取代啦!過兩天又有人大喊 Kotlin 怎麼怎麼不好馬上要涼。Java的好處和適用範圍相信你也明白。而現在還在大量使用的語言都有它各自的優點,這個我就不嘮了,畢竟水平不夠。我是真噁心某些蹭熱度、發軟文各自騙的博主和公眾號。

不要聽信我和谷歌說它好,也不要聽信那些碰瓷博主說它不好,有那時間坐而論道,為啥不抽出半小時來體驗一下 Kotlin 呢?

赞(0)

分享創造快樂