首頁 > 軟體

Kotlin作用域函數使用範例詳細介紹

2023-02-20 06:01:10

這裡我們將介紹Kotlin 5個作用域函數:let,run,with,apply,also。

1 let

let 可用於範圍界定和空值檢查。在物件上呼叫時,let 執行給定的程式碼塊並返回其最後一個表示式的結果。物件可通過參照它(預設情況下)或自定義名稱在塊內進行存取。

所以,總結起來,let 有如下三大特徵:

// 重點11:使用it替代object物件去存取其公有的屬性 & 方法
object.let{
   it.todo()
}
// 重點2:判斷object為null的操作
object?.let{//表示object不為null的條件下,才會去執行let函數體
   it.todo()
}
// 重點3:返回值 = 最後一行 / return的表示式

下面是一些例子(我們可以直接在 Kotlin Playground 中執行):

fun customPrint(s: String) {
    print(s.uppercase())
}
fun main() {
    val empty = "test".let {               // Calls the given block on the result on the string "test".
        customPrint(it)                    // 這裡的 it 就是 "test",所以 "test" 作為輸入給到 customPrint 函數中,列印出大寫的 "test"
        it.isEmpty()                       // let 最後返回的是這個,也就是 empty 最終的值是 false
    }
    println(" is empty: $empty")           // 列印結果 TEST is empty: false。這裡的 TEST 是 customPrint 函數 的列印結果。注意 print 和 println 的區別
    fun printNonNull(str: String?) {
        println("Printing "$str":")
        str?.let {                         // object不為null的條件下,才會去執行let函數體
            print("t")
            customPrint(it)
            println()                      // 換行。let最後返回的是這一行
        }
    }
    fun printIfBothNonNull(strOne: String?, strTwo: String?) {
        strOne?.let { firstString ->       
            strTwo?.let { secondString ->
                customPrint("$firstString : $secondString")
                println()
            }
        }
    }
    printNonNull(null)                    // 列印 Printing "null":
    printNonNull("my string")             // 列印 Printing "my string":
	                                      // MY STRING
    printIfBothNonNull("First","Second")  // 列印 FIRST : SECOND
}

從另一個方面,我們來比對一下不使用 let 和使用 let 函數的區別。

// 使用kotlin(無使用let函數)
mVar?.function1()
mVar?.function2()
mVar?.function3()
// 使用kotlin(使用let函數)
// 方便了統一判空的處理 & 確定了mVar變數的作用域
mVar?.let {
       it.function1()
       it.function2()
       it.function3()
}

2 run

與 let 函數類似,run 函數也返回最後一條語句。另一方面,與 let 不同,執行函數不支援 it 關鍵字。所以,run 的作用可以是:

  • 呼叫同一個物件的多個方法 / 屬性時,可以省去物件名重複,直接呼叫方法名 / 屬性即可
  • 定義一個變數在特定作用域內
  • 統一做判空處理

下面是一些例子:

fun main() {
    fun getNullableLength(ns: String?) {
        println("for "$ns":")
        ns?.run {                                                  // 判空處理
            println("tis empty? " + isEmpty())                    // 這裡我們就發現,在 isEmpty 前不再需要 it
            println("tlength = $length")                           
            length                                                 // run returns the length of the given String if it's not null.
        }
    }
    getNullableLength(null)   
    // 列印 for "null":
    getNullableLength("")
    // 列印 for "":
    //         is empty? true
    //         length = 0
    getNullableLength("some string with Kotlin")
    // 列印 for "some string with Kotlin":
    //         is empty? false
    //         length = 23
    data class People(val name: String, val age: Int) 
    val people = People("carson", 25)
    people?.run{
      println("my name is $name, I am $age years old")
      // 列印:my name is carson, I am 25 years old
    }
}

3 with

with 是一個非擴充套件函數,可以簡潔地存取其引數的成員:我們可以在參照其成員時省略範例名稱。所以說,run 相當於 let 和 with 的集合。

class Configuration(var host: String, var port: Int) 
fun main() {
    val configuration = Configuration(host = "127.0.0.1", port = 9000) 
    with(configuration) {
        println("$host:$port")   // 列印 127.0.0.1:9000
    }
    // instead of:
    println("${configuration.host}:${configuration.port}")    // 列印 127.0.0.1:9000
}

4 apply

apply 對物件執行程式碼塊並返回物件本身。在塊內部,物件由此參照。此函數對於初始化物件非常方便。所以再重複一遍,apply函數返回傳入的物件的本身。

data class Person(var name: String, var age: Int, var about: String) {
    constructor() : this("", 0, "")
}
fun main() {
    val jake = Person()                   
    val stringDescription = jake.apply {  
        // Applies the code block (next 3 lines) to the instance.
        name = "Jake"                                   
        age = 30
        about = "Android developer"
    }.toString()                            
    println(stringDescription)      // 列印 Person(name=Jake, age=30, about=Android developer)
}

5 also

類似 let 函數,但區別在於返回值:

  • let 函數:返回值 = 最後一行 / return的表示式
  • also 函數:返回值 = 傳入的物件的本身
// let函數
var result = mVar.let {
               it.function1()
               it.function2()
               it.function3()
               999
}
// 最終結果 = 返回999給變數result
// also函數
var result = mVar.also {
               it.function1()
               it.function2()
               it.function3()
               999
}
// 最終結果 = 返回一個mVar物件給變數result

另一個類似的例子:

data class Person(var name: String, var age: Int, var about: String) {
             constructor() : this("", 0, "")
}
fun writeCreationLog(p: Person) {
    println("A new person ${p.name} was created.")              
}
fun main() {
    val jake = Person("Jake", 30, "Android developer")   // 1
        .also {                                          // 2 
            writeCreationLog(it)                         // 3
        }
    println(jake)   
    // 最終列印:
    // A new person Jake was created.
    // Person(name=Jake, age=30, about=Android developer)
}

到此這篇關於Kotlin作用域函數使用範例詳細介紹的文章就介紹到這了,更多相關Kotlin作用域函數內容請搜尋it145.com以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援it145.com!


IT145.com E-mail:sddin#qq.com