Trong Kotlin, bất cứ expression nào đều có thể được đánh dấu bằng label.
Label được tạo nên từ định danh của label và @ như abc@, lit@, forTest@…
Để đặt label lên 1 expression, chúng ta chỉ cần đặt label trước expression đó.
Ví dụ 1: đặt loop@ label cho vòng lặp for
1 2 3
loop@ for (i in 1..100) { // ... }
II, Jump expression
Kotlin cung cấp 3 jump expression:
return: mặc định nó sẽ kết thúc function gần nhất chứa nó.
break: kết thúc vòng lập gần nhất.
continue: thực hiện bước tiếp theo của vòng lặp gần nhất.
1, Break và continue
Ví dụ 2: khi i = 3, vòng lặp for có label loop@ sẽ kết thúc.
1 2 3 4 5 6
loop@for (i in1..5) { for (j in1..3) { if (i == 3) break@loop print(j) // Print result: 123123 } }
break kết hợp với label: kết thúc vòng lặp có label đó.
continue kết hợp với label: nhảy đến bước tiếp theo của vòng lặp có label đó.
2, return trong lambada
Mặc định, return sẽ return function gần nhất chứa nó.
Một tác dụng quan trọng khác là dùng return để return lambada expression.
Lambada có label sẽ trùng với tên của function chứa nó.
Trong lambada, Kotlin cho phép:
return có label: kết thúc lambada đó.
return không có label: nếu lambada ở trong inline function thì nó sẽ kết thúc function ngoài gần nó nhất.
Tham khảo bài viết về inline function để hiểu rõ hơn vấn đề này.
Ví dụ 4:return không có label. Do forEach() là inline function nên return kết thúc hàm gần nó nhất là foo()
1 2 3 4 5 6 7 8 9
funfoo() { listOf(1, 2, 3, 4, 5).forEach { if (it == 3) return// non-local return directly to the caller of foo() print(it) } println("this point is unreachable")
// Print result: 12 }
Ví dụ 5:return có label. Chúng ta có thể đặt lit@ cho lambada expression hoặc kotlin cũng đã sinh ra sẵn forEach@.
1 2 3 4 5 6 7 8 9 10
funfoo() { listOf(1, 2, 3, 4, 5).forEach lit@{ if (it == 3) return@lit// local return to the caller of the lambda, i.e. the forEach loop // if (it == 3) return@forEach print(it) } print(" done with explicit label") }
// Print result: 1245 done with implicit label
Ví dụ 6: lambada có label trùng với tên với function chứa chứa nó
Chúng ta không thể dùng break và continue trong lambada do chúng chỉ được dùng trong vòng lặp.
Ví dụ 7: chúng ta dừng việc lặp của list khi item nó bằng 3 và tiếp tục code của foo()
1 2 3 4 5 6 7 8 9 10 11
fun foo(){ run loop@{ listOf(1, 2, 3, 4, 5).forEach { if (it == 3) return@loop// non-local return from the lambda passed to run print(it) } } print(" done with nested loop") }