Kotlin 總結系列(1) —— 基礎要素

kotlin學習總結系列,主要是本身的學習筆記,主要參考自Kotlin 實戰Kotlin官網若有錯誤或者能夠改進的地方,望指出賜教。不積跬步無以致千里,Android知識的龐大,自身知識的不完善,須不斷向大佬學習。java

這一部分主要記錄如何開始使用kotlin現有庫和API,如控制結構、函數聲明、方法聲明,伴生對象和lambda等git

1、 kotlin的一些特性

  1. kotlin是針對java平臺的新編程語言(也是基於jvm),能與java無縫對接。同時有大量實用語法糖幫助咱們快速構建代碼。
  2. kotlin也是一種靜態類型的編程語言,在kotlin中不少狀況下能夠不顯式聲明變量的類型,能夠根據上下文自動判斷,即類型推導。如: val name = "Kotlin",可推斷出name屬於字符串類型
  3. kotlin是偏向於安全式編程的,如能夠有效避免NullPointerException(經過可空類型和一系列可空操做避免,後續會詳解);和ClassCastException,kotlin將檢查和轉換組合成一次操做。如:
if(value is String){          //檢查類型
    println( value.toUpperCase() )       //經過則直接轉換爲改類型
}
複製代碼
  1. 在kotlin中,能夠把多個類放在同一個文件中,文件的名字還能夠隨意選擇,函數也能夠放在類外面。
  2. if、when、try,throw等,都是表達式,而不是語句(後面會有例子)
  3. 建立實例時,不用new ,且不用以 ";" 結尾

2、 基本要素:變量,函數,類和枚舉

簡要說明基本要素的聲明和使用編程

1 變量

kotlin中,變量聲明以關鍵字開始,而後是變量名,最後是類型(能夠不加),如:(建立變量時,不用寫明 new)安全

var i:Int = 24 //顯式指明類型 
val persion = Persion() //不用 new
val name = "Cap"//省略類型
val age :Int //若是還未初始化,必須顯式指明類型,不然沒法推導
age = 24
複製代碼

kotlin中,變量聲明關鍵字只有兩個:val 和 var。 其中,val是不可變引用,至關於java的final聲明;而var則是可變引用至關於java的非final,即普通變量bash

2 字符串模板

kotlin的字符串,像大多數腳本語言同樣,如Groovy,能夠引用局部變量表達式( 在美圓符號$後緊跟表達式 ),使結構更緊湊,如:jvm

val args = arrayOf("John","Ethan")
val name ="index1:$args[0]"  //簡單表達式
val more = "Hello,${if (args.size>0)args[0]else "a"}" //更復雜表達式
println("THis is \$x") //打印結果是 THis is $x,打印$字符時,須要轉義
複製代碼

3 函數

函數分爲代碼塊函數體,和表達式函數體,以下:編程語言

(1)普通函數聲明,即代碼塊函數聲明,其中 a,b是參數,:Int是指函數返回類型函數

fun max(a:Int,b:Int):Int{
    return if (a>b)a else b //if 是表達式而不是語句,能夠直接表明一個值
}
複製代碼

(2)表達式函數體,如上面的例子,是由單個表達式構成的,能夠去掉花括號和return語句,如:學習

fun max(a:Int,b:Int)=return if (a>b)a else b 
複製代碼

注: 對於代碼塊函數體,必須顯式寫出返回類型和return語句ui

4 類

kotlin中函數的聲明,能夠省略大量重複性代碼,尤爲是對於bean類型。如,

class Rectangle(val width:Int,val height:Int)
複製代碼

與如下java定義徹底相同:

public class Rectangle {
    private final int width;
    private final int height;
    
    public Rectangle(int width,int height){
        this.width = width;
        this.height = height;
    }

    public int getWidth() {
        return width;
    }

    public int getHeight() {
        return height;
    }
}
複製代碼

仔細觀察,kotlin的實現是少了public修飾符的,這是由於在kotlin中,public是默認修飾符,關於更多的修飾符和可見性等,後續會詳解

在kotlin中,類屬性的聲明與聲明一個變量同樣,使用 val 和 var 關鍵字,其中val對應final屬性,會默認生成getter;而var對應普通可變屬性,會默認生成getter和setter(亦可自定義setter和getter,後續會詳解)。

對於定義的屬性的訪問,java須要顯式的用getter或setter,而kotlin直接引用名字讀取或賦值,如:

java:

rec.getWidth()
rec.setName() //上面沒定義,只是個普通可變屬性
複製代碼

kotlin:

rec.width  //kotlin底層實現也是調用getter
rec.name = "John" //kotlin底層實現也是調用setter
複製代碼

對於一些能夠即時計算,不須要用字段來支持保存的,能夠自定義getter訪問器,如判斷是不是一個正方形:

class Rectangle(val width:Int,val height:Int){
    val isSquare:Boolean
        get() {
            return width == height
        }
}
複製代碼

屬性isSquare不須要字段保存它的值。使用以下:

val rec = Rectangle(41,42) //不用寫 new
println(rec.isSquare) // 輸出false
複製代碼

5 枚舉

kotlin中的枚舉類用了 enum class兩個關鍵字。和java同樣,枚舉並非值的列表:能夠給枚舉類聲明屬性和方法。

enum class Color(val r:Int,val g:Int,val b:Int){
    RED(255,0,0), GREEN(0,255,0), BLUE(0,0,255);//kotlin中惟一必須用分號的地方
    
    fun rgb() = (r*256+g)*256+b
}
複製代碼

**注:**相互之間用逗號分開。當要在枚舉類定義任何方法時,就要使用分號把枚舉常量列表和方法定義分開,這也是kotlin中惟一必須使用分號的地方

3、 控制結構 -- when

when是switch的替代品,但比swtich更靈活,更強大:

  1. when和if同樣,也是個表達式
  2. 不須要寫上break;
  3. 不一樣於java只能在枚舉、字符串和數字面值中使用,when能夠在結構中使用任意對象;
  4. 多個分支之間,用逗號隔開
//應用上面的枚舉類
fun colorString(color: Color) = when (color){
    Color.RED -> "red"
    Color.GREEN -> "green"
    Color.BLUE -> "blue"
    else -> "pure"
}

//應用在任意結構,如set,分支條件是等式檢查
fun mix(c1:Color,c2:Color) = when (setOf(c1,c2)){
    setOf(Color.RED,Color.BLUE) -> "red * blue"
    setOf(Color.BLACK,Color.WHITE) -> "black * white"
    else -> "else"
}
複製代碼

1 使用不帶參數的when

分支條件能夠是任意的布爾表達式

上面的例子,每次都須要新建一個set,產生額外的垃圾對象,能夠直接使用布爾值表達式來進行對比,如:

fun mixOptimized(c1: Color,c2: Color) = when{
    (c1 == Color.RED && c2 == Color.BLUE) 
            || (c1 == Color.BLUE && c2 == Color.RED) -> "red * blue"
    (c1 == Color.BLACK && c2 == Color.WHITE)
            || (c1 == Color.WHITE && c2 == Color.BLACK) -> "black * white"
    else -> "else"
}
複製代碼

2 智能轉換is在when中的使用

kotlin中,類型檢查和轉換是合併的,is檢查經過後,就默認轉換,如:

class Sum(val left:Int,var right:Int){
    val doubleSum:Int
    get() = 2*field

    init {
        doubleSum = left + right
    }

}

fun printSum(e:Any) = when(e){
    //已經轉換
    is Sum -> println("left:${e.left} , right:${e.right}; sum:${e.doubleSum}")
    else -> println("not")
}// 輸出:left:2 , right:3; sum:10
複製代碼

注:智能轉換隻在變量通過is檢查且以後不會再發生變化的狀況下有效。

3 in 在when中的使用

後面有講解

fun recoginze(c:Char) = when(c){
    in '1'..'9' -> "It's a digit"
    in 'a'..'z' ,in 'A'..'Z' -> "It's a letter"
    else -> "Unknown"
}
複製代碼

4 規則--代碼塊中最後的表達式就是結果

規則--代碼塊中最後的表達式就是結果 ,在全部使用代碼塊並期待獲得一個結果的地方成立。但不能用於代碼塊函數體。

如:

fun max(a:Int,b:Int) = if (a>b){
    println()
    a    //返回 a 值
}else b
複製代碼

4、 基本迭代

1 while迭代

while迭代,與java一致。

2 for迭代

kotlin for循環只有一種形式,與Java 的 for-each類似:for in

2.1 區間和數列

kotlin沒有常規的java for 循環,如,for(int i=0;i<5;i++) 。爲替代這種常見的循環,kotlin使用了區間的概念

區間:就是兩個值之間的間隔,一般是數字-使用 ..運算符來表示區間(val range = 1..10);常應用於 in!in運算符;

區間有兩種常見使用方式:

(1)看成數列迭代,當應用於 int ,long,char時,可看成數列迭代(內部實現了iterator),同時能夠控制迭代的步長,如:

for (i in 1..10){
        println(i)  //輸出 1 2 3 4 5 6 7 8 9 10
    } 
    for (i in 10 downTo 1 step 2){
        println(i) //輸出 10 9 8 7 6 5 4 3 2 1
    } 
    for (i in 10 downTo 1 step 2) {
        println(i) //輸出 10 8 6 4 2
    }
複製代碼

(2) 用於「in」檢查是否在區間中,此時可用於任意實現了Comparable接口類型,"kotlin" in "java".."scala至關於 "kotlin" <="java" && "kotlin"<="scala"; 同時亦能夠用於when中,如:

fun recoginze(c:Char) = when(c){
    in '1'..'9' -> "It's a digit"
    in 'a'..'z' ,in 'A'..'Z' -> "It's a letter"
    else -> "Unknown"
}
複製代碼

2.2 迭代map

kotlin有個實用小技巧,即,根據建來訪問和更新map,如map[KEY] = VALUE

val map = mapOf(1 to "one",2 to "two") //中綴調用,後續詳解
for ((key,value) in map.entries){ //解構聲明,後續會詳解
      ...
      ...
}
複製代碼

2.3 迭代帶有下標的list

val list = listOf<String>()
for ((index,element) in list.withIndex()){
    ...
}
複製代碼

5、 kotlin中的異常

kotlin中的異常與java基本類似,額外區別:

  1. try,throw都是表達式,而不是語句,能夠做爲另外一個表達式的一部分使用,如:
val number = 9
val percentage = 
    if (number in 0 .. 100)
        number 
    else throw IllegalArgumentException("錯誤")
複製代碼

若是條件知足,percentage正常被number初始化,不然,異常拋出,變量也不會初始化。

  1. 在kotlin中,並無區分受檢異常和非受檢異常,全部的異常均可以不顯式try catch
相關文章
相關標籤/搜索