Scope Functions trong Kotlin (let, run, with, apply, also)
1. Giới thiệu
Scope functions thực thi code block trên một object. Có 5 loại: let, run, with, apply, also.
2. let
fun main() {
val name: String? = "Alice"
// Safe call với let
name?.let {
println("Name is $it")
println("Length: ${it.length}")
}
// Chaining
val result = "hello"
.let { it.uppercase() }
.let { "$it!" }
println(result) // HELLO!
}3. run
fun main() {
// run với object
val result = "Hello".run {
println(this)
this.length // return value
}
println(result) // 5
// run không có object
val greeting = run {
val name = "World"
"Hello, $name!"
}
}4. with
fun main() {
val person = Person("Alice", 25)
val description = with(person) {
"Name: $name, Age: $age"
}
println(description)
// Thường dùng khi gọi nhiều methods
with(StringBuilder()) {
append("Hello")
append(" ")
append("World")
toString()
}
}5. apply
fun main() {
val person = Person().apply {
name = "Bob"
age = 30
city = "NYC"
}
// Phổ biến cho builder pattern
val textView = TextView(context).apply {
text = "Hello"
textSize = 16f
setTextColor(Color.BLACK)
}
}6. also
fun main() {
val numbers = mutableListOf(1, 2, 3)
.also { println("Before: $it") }
.also { it.add(4) }
.also { println("After: $it") }
// Logging/debugging trong chain
val result = fetchData()
.also { log("Fetched: $it") }
.map { transform(it) }
.also { log("Transformed: $it") }
}7. Bảng so sánh
| Function | Object Reference | Return Value | Use Case |
|---|---|---|---|
let | it | Lambda result | Null check, transformation |
run | this | Lambda result | Object config + computation |
with | this | Lambda result | Group function calls |
apply | this | Context object | Object configuration |
also | it | Context object | Side effects |
8. Khi nào dùng gì
// let: null check + transformation
user?.let { sendEmail(it.email) }
// run: nhiều operations trả về result
val hexColor = run {
val r = 255
val g = 128
val b = 64
"#${r.toString(16)}${g.toString(16)}${b.toString(16)}"
}
// with: gọi nhiều methods của object
with(config) {
validate()
apply()
save()
}
// apply: configure object, return object
val button = Button().apply {
text = "Click"
onClick = { handleClick() }
}
// also: side effects, debugging
createUser()
.also { logCreation(it) }
.also { notifyAdmin(it) }9. Kết hợp scope functions
data class User(var name: String = "", var email: String = "")
fun createUser(block: User.() -> Unit): User {
return User().apply(block)
}
fun main() {
val user = createUser {
name = "Alice"
email = "alice@email.com"
}.also {
println("Created: $it")
}
}10. takeIf và takeUnless
fun main() {
val number = 42
// takeIf - trả về object nếu true, null nếu false
val evenNumber = number.takeIf { it % 2 == 0 }
println(evenNumber) // 42
// takeUnless - ngược lại với takeIf
val notZero = number.takeUnless { it == 0 }
// Chain với let
val result = number
.takeIf { it > 0 }
?.let { it * 2 }
?: 0
}📝 Tóm tắt
let:it, returns lambda resultrun:this, returns lambda resultwith:this, returns lambda result (không phải extension)apply:this, returns objectalso:it, returns objecttakeIf/takeUnlesscho conditional returns
Last updated on