https://www.jianshu.com/p/5c4a954d2b2c
with
with 是唯一沒辦法作為 Extension Function,會回傳範圍內最後一個物件(lambda result)。範圍內部可以使用 this 來代表原本的物件,甚至有時候可以忽略。
1 fun main() {
2 var a: String = "I'm A"
3
4 var result = with(a) {
5 System.out.println(this)
6 System.out.println(takeLast(1))
7 }
8 }
第 5 行:this 代替了 a 變數,印出 I'm A
第 6 行:takeLast 可以直接忽略 this,回傳 a 字串變數最後一個字元(CharSequence)
其結果為:
I'm A
A
官方建議:
We recommend with for calling functions on the context object without providing the lambda result. In the code, with can be read as “with this object, do the following.”
fun main() { val numbers = mutableListOf("one", "two", "three") with(numbers) { println("'with' is called with argument $this") println("It contains $size elements") } }
run / T.run
run 可視為一個獨立的程式範圍(scope),並且回傳範圍裡最後一個物件(lambda result)。所以下面範例的 result 變數會指派為 a 這個字串變數。
fun main() {
var a = "outside A"
val result = run {
var a = "inside A"
a
}
println(result)
println(a)
}
其結果為:
inside A
outside A
當 run 作為一個 Extension Function 的時候,範圍內部可以使用 this 來代表原本的物件,甚至有時候可以忽略:
1 fun main() {
2 var a = "I'm A"
3
4 a.run {
5 System.out.println(this)
6 val lastChar = takeLast(1)
7 System.out.println(lastChar)
8 }
9 }
第 5 行:this 代替了 a 變數,印出 I'm A
第 6 行:takeLast 可以直接忽略 this,回傳 a 字串變數最後一個字元(CharSequence)
run 因為可以作為 Extension Function,在使用上比 with 更為方便:
1 fun main() {
2 var a: String? = "I'm A"
3
4 var resultRun = a?.run {
5 takeLast(1)
6 }
7 System.out.println("resultRun = $resultRun")
8
9
10 var resultWith = with(a) {
11 this?.takeLast(1)
12 }
13 System.out.println("resultWith = $resultWith")
14 }
因為第 2 行的變數宣告可以為 null,作為 extension function 的 run 可以用 safe call ?. 來判斷是否執行 run 的範圍。
with 則必須在 scope 裡面每次用到 context object 的時候做 safe call 檢查。