1. 程式人生 > >Kotlin開發基礎從0開始(一)

Kotlin開發基礎從0開始(一)

code ... 多說 lang 學習 function ria lis lac

為什麽學習kotlin

kotlin在今年的Google IO 上正式被確認為Android的官方開發語言,想必原因大家也能猜到一二,一是Google與oracle關於Java相關的版權相關的問題,二是kotlin語言很簡潔,不羅嗦,支持很多的新特性。

由於Google都已經官方支持了,語法簡潔高效,和IOS的 swift 很是相似,發展趨勢不可小覷,還有個大新聞就是我們的大神 Jake Wharton 從square 辭職加入了Google,且其在最近的github中國fork了kotlin 倉庫,想必是為kotlin在Android的發展做貢獻,就從這可以斷定kotlin的未來不會太差, 當然作為技術人就需要不斷的學習,不段的挑戰。如果想在Android上繼續深造kotlin肯定是要學習的。

怎麽學習

我的想法是,大家都是學過基本的語言的,比如C,C++,做Android的肯定學過Java,所以我的想法是對照Java的基礎與kotlin基礎做對比著學習, 這樣印象會深刻點,差異化學習。

Kotlin基礎

Kotlin 數據類型

在kotlin語言中,所有的類型都是都是對象,kotlin中沒有了基礎數據類型(int,boolean,char,byte)等。全部換為對象類型。類型如下:
Int,Boolean,String,Byte,Float,Char,Double,Short,這些沒有了Java中隱式拓寬轉換,例如不能把Int類型直接賦值給Long類型了,如要要這樣做這些書類型可以調用如下方法進行轉換:

toByte():   Byte
toShort():  Short
toInt():    Int
toLong():   Long
toFloat():  Float
toDouble(): Double
toChar():   Char
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

kotlin 中各數字類型所占位數如下:

Typebit
Double 64
Long 64
Float 32
Int 32
Short 16
Byte 8

數值常量和Java中基本無區別,十進制:123,十六進制:0x1F。

主要是以下幾種字面值常量:

  • 十進制數值: 123
  • 長整型要加大寫 L : 123L
  • 16進制:0x0f
  • 二進制:0b00001011
  • 默認雙精度浮點數(Double) : 123.5 , 123.5e10
  • 單精度浮點數(Float)要添加 f 或 F :123.5f

註意: kotlin不支持八進制

黑魔法: 在我們寫Int或者Long類型數據時,常常一寫一長串,不便於識別,現在kotlin支持在數字常量中可以添加_了,便於閱讀,不影響數據類型和值,例如電話號碼可以這樣寫了。val phone : Long = 186_****_0814便於我們閱讀。不得不說kotlin語言的靈活性。

kotlin中不會在末尾寫分號啦!!!!!

== 與 ===的區別

在kotlin中多了一種判斷符===三個等號,這個特點呢就是判斷兩個對象是否指向同一個對象,也就是引用相等,而==則表示的數據的結構相等,也就是調用equals方法的返回值。例如:

var a : Int = 3 
println(a===a)  // true 
var b : Int  = a
var c : Int = a
println(b===c) // false 因為指向的對象不是同一個
println(b==c)  // true 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

字符串

字符串有兩種表達方式,一種是可以帶轉義符的,另外一種是可以包含任意字符的。例如下面有轉義的val s = "hello world \n" ,但如果真正的字符串就是上面帶有轉義字符\n的,那麽要怎麽表示呢,kotlin中使用三引號 """來表示,例如:val s = """hello world \n""" 這樣\n就不會被轉義為回車,而是原封原樣的字符串了。

字符串還有了很好的模板特性,會極大的方便字符串拼接,操作等。下面就直接看例子:

val a = 1
var str : String = "this num is $a"
a = 2
val s2 = "${str.replace("is", "was")}, but now is $a"
  • 1
  • 2
  • 3
  • 4

可以看到這極大的方便字符串的操作,使用$即可直接取到變量的值,如果在字符串中操作則使用表達式${}直接對字符串進行操作。

控制流

控制流基本與java中常用的保持一致,有for,while,但switch在kotlin中換為when,學過其他語言的應該都能很容易的掌握。

for 循環

for循環使用 in 關鍵字進行遍歷,普通的如下:

val array = 1..100
for (value in array) {
    print("value = $value")
}
  • 1
  • 2
  • 3
  • 4

對於之前for循環的步長使用step來表示

for (i in 1..100 step 2) {
    print("i = $i")
}
// 1..100  表示是閉區間 ,[1,100]
  • 1
  • 2
  • 3
  • 4

為了表示開閉區間,可以使用until 來表示。如下:1 until 100 表示 [1,100)

倒序的話將..替換為downTo

while循環

while 循環與java 一樣,不在多說,以及do while

when

when 的功能與java switch 功能類似,但是其便捷性不僅僅能case 一些基本數據類型,它可以支持表達式,這樣會更加的靈活便捷。下面看個例子吧:

fun describe(obj: Any): String =
    when (obj) {
        1,‘1‘ -> "One"
        "Hello","Good" -> "Greeting"
        is Long -> "Long"
        !is String -> "Not a string"
        else -> "Unknown"
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

看到上面的是不是很靈活? 可以對不同的類型在同一個分支中進行判斷,極大的提高了靈活性。

集合

  • 數組:

在Kotlin中使用Array來表示數組,它本身定義了set,get,size等屬性,可以使用arrayOf來創建數組,例如:var test = arrayof(1,2,3),數組中的數據類型可以是任何類型,但是使用時需要註意類型,訪問可以用get(index) 或者[index]來訪問,

for (ar in array) {
    print("array value = $ar")
}

for (i in array.indices) {
    print("array value = $array[i]")
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • List

list的創建也很簡便,使用listOf創建,使用val list = listOf(1,2,3,"string"), 當然遍歷也提供了多種方式,如下:

for (it in list) {
    print("list value = $it")
}
// 帶下標,以及值的遍歷方式
for ((index,value) in list.withIndex()) {
    print("index = $index value = $value " )
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • Map

map的創建val map = mapOf("a" to 1, "b" to 2, "c" to 3),訪問也是很簡單,比java中訪問簡單太多,方式如下:

for ((key, value) in map) {
    print("key = $key  value = $value")
}
  • 1
  • 2
  • 3

看到上面常見集合的類型套路都是一樣使用類型Of()來創建,訪問遍歷也是很方便。

空安全

在kotlin是空類型安全的,所以如果要給一個變量賦值為null,則必須在其定義後面加上?,否則無法編譯器會報錯。

var str : String ? = null 
var  size =  str.length   //此時會編譯報錯,提示可能為空
  • 1
  • 2

那麽怎麽獲取呢,在kotlin中提供兩種方法來訪問,第一種為?.的訪問形式,此種表示如果為空則不執行,非空再繼續,則上面則可以寫成這樣val size = str?.length,第二種就是可能在執行前給變量賦值了,我們肯定它不為空,那麽可以用!!.來獲取,如下:val size = str!!.length,當然第二種你必須為運行時控制住做好心理準備。

變量

在Java中變量有普通的變量,靜態常量(final),靜態編量(static),但在kotlin中沒有static關鍵字了,需要使用靜態變量有另外的一種表示,後續在將這部分,那在kotlin中的變量的表示方式為var,常量的表達方式為val, 具體表達方式如下:

val a :Float = 1f, val a = "Aaron", var c :Int = 2, c += 2
kotlin中定義的類型是放在變量後面的,且類型有時可省略。

var a : Int = 2, var a = 2 這兩個表達的是一樣的,後面的表達式會進行自動類型推倒。

kotlin是空類型安全的,所以在賦值時也有些差別,如果想要空類型的則在賦值後面需要加

延遲屬性

延遲屬性或者延初始化可以幫助我們在需要用到時在初始化,不需要時不初始化,幫助程序節省內存空間及啟動速度。

在kotlin中使用lazy關鍵字來表示。直接看下面的例子:

val answer by lazy {
    println("Calculating the answer...")
    42
}
if (needAnswer()) { // 返回隨機值
    println("The answer is $answer.") // 此時計算出答案
}else {
    println("Sometimes no answer is the answer...")
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

只有執行到上面needAnswer()為true時,answer才會被初始化。
想想是不是我們寫的很多初始化的代碼,都可以用lazy來延遲初始化了。

  • 註意by lazy所賦值的變量必須為val類型

函數

函數在kotlin中使用 fun 來表示,函數參數與定義變量一樣放在變量後面,參數的類型不可省略,返回值也是在放在參數括號後面,當沒有返回值的時候使用Unit代替 java中的void關鍵字,當然Unit也是可以省略的。下面我們看幾個例子:

fun sum(a: Int, b: Int): Int {
    return a + b
}
// 等同於下面語句,簡稱函數式表達式
fun sum(a:Int, b:Int) = a + b

val sum = {x:Int ,y:Int -> x + y}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

上面就是一個簡單的函數,有參數又返回值。

fun printSum(a: Int, b: Int): Unit {
  println("sum of $a and $b is ${a + b}")
}
// 等同於下面
fun printSum(a: Int, b: Int) {
  println("sum of $a and $b is ${a + b}")
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

上面則為沒有返回值,其可以將函數後面的Unit省略掉。

函數默認參數

在java中我們如果對同一個方法名,但是有不同的參數個數,需要寫多個方法出來,看起來很臃腫,對於少參數的來說,可能就是某個參數為固定或者默認值,那麽在kotlin中有了默認參數的表示方式。例如:

fun sum(a :Int , b : Int = 3) : Int {
    return a +b
}

//調用 sum(1,2) // 代表 1 + 2 
//調用 sum (2)  // 代表2 + 3 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
函數具名參數

具名參數是對上面的一種特殊情況的考慮,比如我們將上面的代碼改為如下:

fun sum(a :Int = 3, b : Int) : Int {
    return a +b
}
//調用 sum (2)   此時對於此調用,編譯器認為2 是為a賦值,而b沒有賦值,無法編譯通過。那麽要調用則采用具名參數來指明參數。
// 改為 sum(b = 2) 這樣既可指定將2賦值給b,則a使用默認的值。 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
擴展函數

在Android可能很常見的是有一個Utils包,專門放置一些常用的公共方法,比如String,Toast,File 操作等等,然而現在kotlin可以直接對系統類,進行擴展。

fun Context.toast(message: CharSequence, duration: Int = Toast.LENGTH_SHORT) {
    Toast.makeText(this, message, duration).show()
}
//在Activity,Context實例中就可以直接調用了。
toast("我是Toast")
  • 1
  • 2
  • 3
  • 4
  • 5

總結

上面講述了kotlin 很基礎的知識,講解了些kotlin的特性,當然還有很多的特性,以及在Android上開發的便捷性等等,本篇就先說這麽多,下一篇將會說到kotlin更多的特性,比如:自定義類的getter和setter 方法,inline 函數,高階函數,數據類,單例類等。敬請期待!

Kotlin開發基礎從0開始(一)