Kotlin For Android 筆記(二)

1、當(dāng)方法參數(shù)不定的時(shí)候,我們可以使用 vararg 聲明,這樣就可以傳入多個(gè)值了;但每個(gè)方法只能聲明一個(gè) vararg
fun printSum(vararg numbers: Int) {
    val sum = numbers.sum()
    print(sum)
}
printSum(1,2,3,4,5) // Prints: 15
printSum() // Prints: 0

// 可以直接傳遞數(shù)組(但是要以 * 為前綴)
val texts=arrayOf("b","c","d")
printAll(*texts)
2、當(dāng) when 的參數(shù)為空時(shí),可以省略 ()
                                                  // 這里省略了 `()`
override fun onOptionsItemSelected(item: MenuItem?)=when{
        item?.itemId==R.id.design_menu_item_action_area->{
            onBackPressed()
            true
        }
        else -> super.onOptionsItemSelected(item)
}
3、Default arguments value versus Named arguments syntax
fun printValue(value: String, inBracket: Boolean = true,prefix: String = "", suffix: String = "") {
    print(prefix)
    if (inBracket) {
        print("(${value})")
     } else {
        print(value)
    }
    println(suffix)
}

printValue("str", true, "","") // Prints: (str)
printValue("str") // Prints: (str)
printValue("str", false) // Prints: st

//命名式參數(shù)
printValue("str", suffix = "!") // Prints: (str)!
四、Top-level function

使用 Android 項(xiàng)目,Kotlin 被編譯成運(yùn)行在 Dalvik 上的 Java 字節(jié)碼。虛擬機(jī)(安卓 5.0 之前)或安卓運(yùn)行時(shí)(安卓 5.0 及更高版本)。兩個(gè)虛擬機(jī)都只能執(zhí)行類內(nèi)定義的代碼。為了解決這個(gè)問(wèn)題,Kotlin 編譯器為頂級(jí)函數(shù)生成類。這個(gè)類名由 文件名kt 后綴構(gòu)成。在這樣的 class 里函數(shù)和屬性是靜態(tài)的。例如,假設(shè)我們定義了 printer.kt 文件中的函數(shù):

// Printer.kt
fun printTwo() {
    print(2)
}

將 kotlin 代碼編譯成 Java 字節(jié)碼。生成的字節(jié)碼將類似于下面的 Java 類生成的代碼:

//Java
public final class PrinterKt { // 1
  public static void printTwo() { // 2
      System.out.print(2); // 3
    }
}

1、printerkt 是由 文件名kt 后綴組成的名稱。
2、所有頂級(jí)函數(shù)屬性都編譯為靜態(tài)方法和變量
3、print 是一個(gè) kotlin 函數(shù),但由于它是一個(gè)內(nèi)聯(lián)函數(shù),因此它的調(diào)用被替換為
它在編譯期間的主體。它的主體只包含 system.out.println 的調(diào)用

我們還可以在 Java 文件中訪問(wèn) Kotlin 頂級(jí)函數(shù)。用類名前綴函數(shù)調(diào)用:

//Java file, call inside some method
PrinterKt.printTwo()

正如我們所看到的,Kotlin 與 Java 是可以互操作的。為了使 Kotlin 的頂級(jí)方法,在 Java 中使用更加方便,我們可以添加一個(gè)可以更改名稱的 annotation (這個(gè)注解一定要放在 package 的上面) 一個(gè) JVM 生成的類。這樣在 Java 中調(diào)用 Kotlin 的頂級(jí)方法和屬性是很方便的。類似下面這樣:

@file:JvmName("Printer")

接著就可以在 Java 文件使用了。Printer.printTwo()

五、Local functions(局部方法)
fun makeStudentList(): List<Student> {
    var students: List<Student> = emptyList()
  fun addStudent(name: String, state: Student.State =  Student.State.New) {
    students += Student(name, state, courses = emptyList())
  }
  // ...
  addStudent("Adam Smith")
  addStudent("Donald Duck")
  // ...
  return students
}

這樣寫有一個(gè)好處就是,可以直接使用當(dāng)前方法的變量,不需要去傳遞;如果把它提取為成員方法,那就需要傳遞所需要的參數(shù),如果調(diào)用修改了參數(shù)的形式,那函數(shù)的聲明也需要重新修改,這樣就導(dǎo)致了要修改兩個(gè)地方(Java 中經(jīng)常出現(xiàn)這樣的問(wèn)題)。

六、自定義 getter/setter
class Student {
    var age: Int?//自定義 get/set 方法
        get() = age
        set(value) {//value 是自定義的變量名,名字可以隨便起
            age = value
        }
}
image.png

這樣會(huì)爆出堆棧錯(cuò)誤?。?!讓我們來(lái)看一下 Student 的 class 文件


image.png

果然,造成了堆棧溢出(recursive call)

這時(shí)候使用 Kotlin 提供的備用字段(關(guān)鍵字 field)即可解決這個(gè)問(wèn)題

class Student {
    var age: Int? = 0
        get() = field //使用備用字段自定義 get/set 方法
        set(value) {
            field = value
        }
}

再次查看 class 文件發(fā)現(xiàn)代碼也正常了


image.png

備用字段 field 的使用范圍僅限于當(dāng)前屬性的 get/set 方法。

以下兩種情況不支持 field (寫了也沒效果)字段

① 因?yàn)榈谝淮晤悇?chuàng)建的時(shí)候,屬性的值就被計(jì)算了(后續(xù)的值不會(huì)再起作用)

class Fruit(var weight: Double) {
    val isHeavy = weight > 20
}
    var fruit = Fruit(7.0)
    println(fruit.isHeavy) // Prints: false
    fruit.weight = 30.5
    println(fruit.isHeavy) // Prints: false

② 因?yàn)樗闹悼偸鞘褂昧硪粋€(gè)屬性計(jì)算的。

class Car {
    var usable: Boolean = true
    var inGoodState: Boolean = true
    var crashed: Boolean
    get() = !usable && !inGoodState
    set(value) {
      usable = false
      inGoodState = false
  }
}

如果類沒有主構(gòu)造函數(shù),而超類有一個(gè)非空的構(gòu)造函數(shù),然后每個(gè)次構(gòu)造函數(shù)必須使用 super 關(guān)鍵:

class ProductView : View {
    constructor(ctx: Context) : super(ctx)
    constructor(ctx: Context, attrs : AttributeSet) super(ctx, attrs)
}
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容