用Kotlin簡化代碼

自從谷歌在IO大會上將kotlin指定爲Android的一級語言,kotlin的人氣是刷刷刷的往上飆啊,既然如此,讓我們來看看kotlin有什麼好處,谷歌爲啥要把它作爲Android的一級語言呢

1. 100%兼容java

這個是最重要的一點了,由於kotlin也是運行在 JVM上,而且連編譯出來的字節碼文件都是一樣的,甚至直接就用了jdk,直接使用java的庫,所以這樣看來,kotlin和java是100%兼容的。

你可以在java中調用kotlin文件,也可以在kotlin中使用java文件

2. 類型的自動判斷

其實並不是沒有了類型,只是幫你自動判斷了,便捷了很多

//這就是一個Int了
var a = 1
//這就是一個String了
var b = "string"
//如果你想要給他們賦值,還是要注意類型的
a = b //這可是會報錯的

當然,如果你覺得不爽的話,給他們一個類型也是可以的,不過這樣就很多餘了

val a: Int = 1

還有更智能的呢

if(a is User)
{
    a = b.getUser()
}

你要是在java裏面這麼寫還不得給編譯器抱怨死,不給他一個強制類型轉換肯定是不行的,而在kotlin裏面,編譯器顯然要聰明很多,發現你前面判斷過了,就給你直接賦值了

3. 自動拆裝箱

這也算是填了java的一個坑吧,在kotlin中你再也不需要去考慮到底是用int還是Integer了,因爲在kotlin中全部都用Int,至於判斷全部交給它自己去判斷了

4. 數據類(data class)

對於我們經常創建的那些pojo,kotlin也對他們做了語法上的支持,那就是data class。

在data class中封裝了很多東西,比如get/set、tostring、hashCode等方法,以後定義pojo就簡單了很多

data class User(val name: String, val age: Int)

當然這裏面還是有點坑的,因爲kotlin中默認class都是final的,而且data默認是沒有空的構造的,這就導致我們寫程序時候出現了很多奇怪的錯誤

不過還好,官方出了noarg和allopen兩個插件幫我們解決了這個問題

5. 擴展方法

在kotlin中我們可以給我們的任意類擴展方法,看一下例子就明白了

fun main(args: Array<String>)
{
    println(2.pow2()) //4.0
}

fun Int.pow2() = Math.pow(this.toDouble(), 2.0)

在這裏我們給Int類擴展了一個二次方方法,我們甚至還可以重載運算符

fun main(args: Array<String>)
{
    val point = Point(2.3,4.5)
    println(-point)  //Point(x=-2.3, y=-4.5)
}

data class Point(var x: Double, var y: Double)
{
    operator fun unaryMinus() = Point(-x, -y)
}

6. 字符串拼接

在kotlin中,拼接字符串再也不像以前那樣一堆加號一個個拼,實在太累了,看看kotlin是怎麼做的

val a = "你好"
val point = Point(2.3,4.5)
println("$a,我的座標是x=${point.x},y=${point.y}")
//你好,我的座標是x=2.3,y=4.5

這樣是不是方便了很多

7. 選擇判斷

1. if表達式

kotlin中的if else也是有返回值的

Java:

if (a>b){
   max=a;
   }else{
       max=b;
   }

Kotlin:

val max = if(a > b) a else b

這樣寫也是可以的

val max = if (a > b) {
    println("a=$a")
       a
   } else {
       println("b=$b")
       b //默認最後一行是返回值
   }

2. when

Java:

switch(a)
{
  case 1:
    System.out.println(a);
    break;
  case 2:
    System.out.println(a);
    break;
  case 3:
    System.out.println(a);
    break;
  default:
    System.out.println(a);
}

Kotlin:

when(a)
{
  1->println(a)
  1,2->println(a)
  //還可以這樣
  in 3..33->println(a)
  !in 200..500->println(a)
  //甚至可以這樣
  Math.max(7,9)->println(a)
  //只要你能想到的,都可以試試,無論是函數還是字符串、Any什麼的
  else->println(a)
}

還可以不要判斷條件,這樣默認判斷boolean

when
{
  x>10->println(1)
  x<10->println(2)
  else->print(10)
}

7. lambda表達式

在kotlin中大量的使用了lambda表達式,這使得代碼簡化了很多

//其中view就是it
btn.setOnClickListener {
            val text = it.getText().toString()
            log.i(this, text)
        }
//如果看不慣,可以改成這個樣 
btn.setOnClickListener {view ->
            val text = view.getText().toString()
            log.i(this, text)
        }

還可以用::來引用一個方法

val array = arrayListOf<String>("a","b","c")
array.forEach ( ::println )

這樣就可以把所有的元素打印出來了

下面就是kotlin中最驚豔的一部分了

8. Null安全

null曾經被戲稱爲“十億美金的錯誤”,不過也確實,null雖然好用,但是導致很多錯誤的元兇往往都是他

在Kotlin中,編譯器是可以識別你的引用是否是null,進而提醒你。

默認的,kotlin中所有的對象都是不爲null的,如果需要你可以在對象後加上一個?表示此對象可以爲null,但這是不被提倡的

data class hello(var name: String?)

對於一個可空對象,你也可以使用!!來強制使他不報錯,但是建議除非萬不得已不要使用

val len = a!!.length

對於Java中的強制類型轉換,在Kotlin中變爲了安全轉型,在無法轉型時不會報ClassCastException,而是直接返回null

val a = b as String

安全調用(?.)

Java:

int len = null;
if(a != null)
  len = a.length();

Kotlin:

var len =a?.length()

甚至這樣都可以

//只要有一個爲null就返回null
d = a?.b?.c?.length()

Elvis 操作符(?:)

Java:

int len;
if(a != null)
  len = a.length();
else
  len = 0;

Kotlin:

val len = a?.length ?: 0

9. 操作符

kotlin中內置了很多的操作符,這大大減輕了我們的工作負擔,讓我們來看幾個

forEach

val list1 = listOf(1..34, 4..7)
val list2 = listOf(2,4,6,23,87)

//這個之前也提到過,很多語言都已經有了,可以把集合遍歷
//可以結合lambda表達式,對元素進行操作
list2.forEach { print("$it ") }
list1.forEach {it.forEach { print("$it ") }}
//forEach並沒有返回值,所以這樣的操作其實是無效的
list2.forEach{it*2}

map

//map(遍歷,返回list)
val newList = (1..30).map { it * 2 + 3 }
newList.forEach(::println)

flatMap

//flatMap(將多重集合平鋪,返回list)
val newList2 = list1.flatMap { it }
newList2.forEach(::println)

reduce

//reduce(遍歷並對每一項進行操作,並將值賦給acc進行累計,函數返回值爲acc)
val newList3 = list2.reduce { acc, i -> i+acc }
println(newList3)

fold

//fold(有初始值的reduce,還可以進行字符串操作等)
println(list2.fold(5){acc, i -> i+acc })
println(list2.fold(StringBuffer()){acc, i -> acc.append("$i,") })

filter和takeWhile


//filter(lambda表達式返回爲false時過濾)
println(list2.filter { it%2==1 })

//takeWhile(lambda表達式返回false時結束)
println(list2.takeWhile { it%2==0 })

let、apply、run

//let(默認當前對象爲it,返回值爲最後一行)
println(list2.let {
    it.toString()
    it[1]
})

//apply(在函數內可以直接調用該對象的方法,返回該對象)
println(list2.apply{
    toString()
    get(1)
})

//run(在函數內可以直接調用該對象的方法,返回最後一行)
println(list2.run {
    toString()
    get(1)
})

可以看到這三個函數差距不大,他們最大的用處就是和 ?. 一起進行非空判斷後的操作,這樣代碼寫起來很簡潔

use


//use(將自動把對象進行close,try,catch等操作)
BufferedReader(FileReader("hello.txt")).use {
    var line : String?
    while(true)
    {
        line = it.readLine() ?: break
        println(line)
    }
}
//簡化(readText()直接讀取文件)
println(BufferedReader(FileReader("hello.txt")).use { it.readText() })

總結

這些並不是kotlin的全部,我只是將我覺得不錯的點拿出來說一說,還有更多的祕密等着你去挖掘呢

當然,kotlin現在作爲一門新興語言,還有很多缺點和不成熟的地方,不過每一門新語言剛出來都是這樣,最後還是靠着大家的力量和智慧把他們都一一解決,當年java剛出來那麼多人不看好,可最後事實卻證明了一切

總的來說,kotlin就是集合了很多語言的優點爲一體的一門語言,說的難聽一點就是東抄一點西抄一點,然後組合起來。但是這又有什麼呢,對於一門語言來說,集百家之長是很正常的事,只要好用就行了嘛

———————————————————————————————

我看見網上關於kotlin和java很多人在對噴,我也想說幾句。

kotlin和java的關係就與object c和swift的關係,就像是一個升級版和簡化版,但是這麼多年了,大家看見了oc沒人用了麼,更何況java比oc的應用場合多了去了,所以java會被淘汰我是不相信的,不過kotlin也確實是一個趨勢,以後使用kotlin肯定是有優勢的

大家都是從java一路走來的,對java有感情很正常,但我想這不是拒絕kotlin的理由吧,作爲一個搞IT行業的,始終向前看應該是最基本的吧,更何況現在谷歌將kotlin作爲一級語言,spring5也對kotlin進行了大量支持,既然大家都很看好他,我們又有什麼理由拒絕呢?

至於在噴kotlin是個糖盒的我就更不明白了,有糖喫不好麼?作爲一門面向對象的語言,用語言層次給我們支持不好麼,難道大家都要去用匯編寫程序麼?

我覺得在這個快節奏的時代,能夠提高生產力的語言更是值得推廣,如果我們始終抱着守舊的思想,那恐怕在這個有着前所未有的發展速度的時代,我們很快就會被淘汰

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章