Kotlin 中作用域函式的使用
- Kotlin 中的作用域函式
- 在 Kotlin 中使用範圍函式
-
在 Kotlin 中使用
also
範圍函式 -
在 Kotlin 中使用
let
作用域函式 -
在 Kotlin 中使用
apply
範圍函式 -
在 Kotlin 中使用
run
作用域函式 -
在 Kotlin 中使用
with
作用域函式
本文將討論 Kotlin 中的作用域函式 also
。我們還將介紹 Kotlin 中可用的其他作用域函式。
但首先,讓我們瞭解什麼是作用域函式。
Kotlin 中的作用域函式
Kotlin 有許多專門為在物件上下文中執行一段程式碼而建立的函式。這些函式稱為作用域函式。
當我們使用 lambda 表示式呼叫時,作用域函式會為物件建立一個臨時作用域。Kotlin 中有 5 個作用域函式,分別是 also
、let
、apply
、run
和 with
。
雖然 Kotlin 中的所有作用域函式都執行相同的功能,但不同之處在於該塊內的物件在執行後如何可用。根據返回值和物件引用,我們需要選擇五個作用域函式之一。
下表顯示了每個作用域函式的物件引用和返回值。
範圍函式 | 物件參考 | 返回值 | 擴充套件函式 |
---|---|---|---|
also |
it |
蘭姆達值 | 它是一個擴充套件函式。 |
let |
this |
蘭姆達值 | 它是一個擴充套件函式。 |
apply |
- | 蘭姆達值 | 它不是一個擴充套件函式。 |
run |
this |
蘭姆達值 | 它不是一個擴充套件函式。 |
run |
this |
上下文物件 | 它是一個擴充套件函式。 |
with |
it |
上下文物件 | 它是一個擴充套件函式。 |
在 Kotlin 中使用範圍函式
下面的示例演示了在 Kotlin 中使用範圍函式。在這段程式碼中,我們將使用 let
函式為物件 Students 建立範圍。
data class Student(var firstName: String, var lastName: String, var age: Int, var address: String) {
fun moving(newAddress: String) { address = newAddress }
fun ageIncrease() { age++ }
}
fun main() {
Student("David", "Miller", 24, "New York").let {
println(it)
it.moving("Chicago")
it.ageIncrease()
println(it)
}
}
輸出:
範圍函式在輸出中將 Student 物件稱為 it
。如果不使用作用域函式,我們將不得不宣告一個新變數並使用 Student 物件的值對其進行初始化以訪問它。
在 Kotlin 中使用 also
範圍函式
如上表所述,Kotlin 中的 also
函式提供了一個上下文物件作為引數 (it
)。當我們需要執行將上下文物件作為任何函式的引數的操作時,我們可以使用 also
。
在 Kotlin 中使用 also
的另一個好方法是當我們需要直接引用物件本身而不是其屬性或函式時。參考下面的例子來理解 Kotlin 中的 also
函式。
fun main() {
val numList = mutableListOf("one", "three", "five")
numList
.also { println("Elements in the list before adding a new one: $it") }
.add("seven")
println("Elements in the list after adding a new one: " + numList)
}
輸出:
在 Kotlin 中使用 let
作用域函式
Kotlin 中的 let
範圍函式提供上下文物件作為引數 it
。它的返回值是 lambda 執行的結果。
我們可以使用 let
函式呼叫多個函式來累積呼叫鏈的結果。
fun main() {
val numList = mutableListOf("one", "three", "five", "seven", "nine")
val resList = numList.map { it.length }.filter { it > 3 }
println(resList)
}
輸出:
[5,4,5,4]
我們可以使用 let
範圍函式來列印 lambda 結果,而不是在上面的示例中使用 resList
。
fun main() {
val numList = mutableListOf("one", "three", "five", "seven", "nine")
numList.map { it.length }.filter { it > 3 }.let{
println(it)
//We can add more functions here
}
}
輸出:
[5,4,5,4]
如果程式碼只有一個函式,我們可以將 lambda (it
) 替換為方法引用符號 (::
)。
fun main() {
val numList = mutableListOf("one", "three", "five", "seven", "nine")
numList.map { it.length }.filter { it > 3 }.let(::println)
}
輸出:
[5,4,5,4]
在 Kotlin 中使用 apply
範圍函式
在 Kotlin (this
) 中使用 apply
函式時,上下文物件可用作接收器。我們可以在沒有任何返回值的程式碼塊上使用 apply
函式。
最常見的用例是在物件配置期間。參考下面的示例,我們建立了一個 Student 物件,然後對其進行配置。
data class Student(var Name: String, var age: Int = 0, var address: String = "")
fun main() {
val david = Student("David Miller").apply {
age = 24
address = "New York"
}
println(david)
}
輸出:
在 Kotlin 中使用 run
作用域函式
在 Kotlin 中使用 run
函式時,我們將上下文物件作為接收者 (this
)。lambda 執行結果本身就是這個作用域函式的返回值。
當 lambda 同時具有物件初始化和返回值的計算時,run
函式最有用。
class port(var url: String, var portNum: Int) {
fun initialRequest(): String = "Initial default request"
fun res(request: String): String = "This is the result of query '$request'"
}
fun main() {
val portService = port("https://example.kotlinlang.org", 80)
val finalResult = portService.run {
portNum = 8080
res(initialRequest() + " to port $portNum")
}
// the same code written with let() function:
val letResult = portService.let {
it.portNum = 8080
it.res(it.initialRequest() + " to port ${it.portNum}")
}
println(finalResult)
println(letResult)
}
輸出:
我們也可以在 Kotlin 中使用 run
作為非擴充套件函式。這意味著它將執行一個需要表示式的語句塊。
fun main() {
val hexNum = run {
val dig = "0-9"
val hexDig = "A-Fa-f"
val indication = "+-"
Regex("[$indication]?[$dig$hexDig]+")
}
for (match in hexNum.findAll("+139 -ABFF 79")) {
println(match.value)
}
}
輸出:
+139
-ABFF
79
在 Kotlin 中使用 with
作用域函式
with
函式也是一個非擴充套件函式,例如 run
。with
函式的特點是它作為引數傳遞但可作為接收器使用。
with
最適合在我們不想提供 lambda 結果的上下文物件上呼叫函式。
fun main() {
val num = mutableListOf("one", "three", "five", "seven")
with(num) {
println("The function 'with' is called with argument $this")
println("The function contains $size items")
}
}
輸出:
Kailash Vaviya is a freelance writer who started writing in 2019 and has never stopped since then as he fell in love with it. He has a soft corner for technology and likes to read, learn, and write about it. His content is focused on providing information to help build a brand presence and gain engagement.
LinkedIn