Hàm (Function) trong Kotlin
🎯 Mục tiêu: Nắm vững cách định nghĩa và sử dụng hàm trong Kotlin với các tính năng hiện đại như default parameters, named arguments, và single-expression functions.
💡 Khái niệm
Hàm là block code có thể tái sử dụng, nhận input (parameters) và có thể trả về output (return value).
fun greet(name: String): String {
return "Hello, $name!"
}
fun main() {
println(greet("Kotlin")) // Hello, Kotlin!
}📝 Cú pháp định nghĩa hàm
Hàm cơ bản
fun functionName(param1: Type1, param2: Type2): ReturnType {
// body
return value
}Hàm không có giá trị trả về (Unit)
fun printMessage(message: String): Unit {
println(message)
}
// Unit có thể bỏ qua
fun printMessage(message: String) {
println(message)
}⭐ Single-Expression Functions
Khi hàm chỉ có một biểu thức, dùng =:
// Full syntax
fun sum(a: Int, b: Int): Int {
return a + b
}
// Single-expression (type inferred)
fun sum(a: Int, b: Int) = a + b
// Ví dụ khác
fun isEven(n: Int) = n % 2 == 0
fun double(x: Int) = x * 2
fun greet(name: String) = "Hello, $name!"🎯 Default Parameters
fun greet(name: String = "Guest", greeting: String = "Hello") {
println("$greeting, $name!")
}
fun main() {
greet() // Hello, Guest!
greet("Alice") // Hello, Alice!
greet("Bob", "Hi") // Hi, Bob!
}🏷️ Named Arguments
Gọi hàm với tên tham số để code rõ ràng hơn:
fun createUser(
name: String,
age: Int,
email: String,
isAdmin: Boolean = false
) {
println("User: $name, $age, $email, admin=$isAdmin")
}
fun main() {
// Positional arguments
createUser("Alice", 25, "[email protected]")
// Named arguments - rõ ràng hơn
createUser(
name = "Bob",
age = 30,
email = "[email protected]",
isAdmin = true
)
// Có thể đổi thứ tự với named arguments
createUser(
email = "[email protected]",
name = "Charlie",
age = 28
)
}📦 Vararg - Số lượng tham số không giới hạn
fun sum(vararg numbers: Int): Int {
var total = 0
for (n in numbers) {
total += n
}
return total
}
fun main() {
println(sum(1, 2, 3)) // 6
println(sum(1, 2, 3, 4, 5)) // 15
// Spread operator để truyền array
val arr = intArrayOf(1, 2, 3)
println(sum(*arr)) // 6
}🔄 Return Types
Explicit return type
fun multiply(a: Int, b: Int): Int {
return a * b
}Inferred return type (single-expression)
fun multiply(a: Int, b: Int) = a * bNothing - hàm không bao giờ return
fun fail(message: String): Nothing {
throw IllegalStateException(message)
}
fun validateAge(age: Int): Int {
if (age < 0) fail("Age cannot be negative")
return age
}🛠️ Thực hành
Bài tập 1: Tính giai thừa
fun main() {
// TODO: Viết hàm factorial(n)
// factorial(5) = 5! = 120
}Lời giải:
fun factorial(n: Int): Long {
var result = 1L
for (i in 2..n) {
result *= i
}
return result
}
// Hoặc recursive
fun factorialRecursive(n: Int): Long =
if (n <= 1) 1 else n * factorialRecursive(n - 1)
fun main() {
println(factorial(5)) // 120
println(factorialRecursive(5)) // 120
}Bài tập 2: Kiểm tra số nguyên tố
fun main() {
// TODO: Viết hàm isPrime(n)
}Lời giải:
fun isPrime(n: Int): Boolean {
if (n < 2) return false
for (i in 2..kotlin.math.sqrt(n.toDouble()).toInt()) {
if (n % i == 0) return false
}
return true
}
fun main() {
println(isPrime(17)) // true
println(isPrime(20)) // false
// In 10 số nguyên tố đầu tiên
println((2..100).filter { isPrime(it) }.take(10))
}Bài tập 3: Format tên
fun main() {
// TODO: Viết hàm formatName với options
// formatName("nguyen van a")
// formatName("nguyen van a", uppercase = true)
// formatName("nguyen van a", reverse = true)
}Lời giải:
fun formatName(
name: String,
uppercase: Boolean = false,
reverse: Boolean = false
): String {
var result = name.trim()
.split(" ")
.filter { it.isNotBlank() }
.joinToString(" ") { it.replaceFirstChar { c -> c.uppercase() } }
if (uppercase) result = result.uppercase()
if (reverse) result = result.split(" ").reversed().joinToString(" ")
return result
}
fun main() {
println(formatName("nguyen van a")) // Nguyen Van A
println(formatName(" nguyen van a ")) // Nguyen Van A
println(formatName("nguyen van a", uppercase = true)) // NGUYEN VAN A
println(formatName("nguyen van a", reverse = true)) // A Van Nguyen
}📱 Trong Android
// Extension function for View
fun View.show() { visibility = View.VISIBLE }
fun View.hide() { visibility = View.GONE }
// Reusable validation
fun validateEmail(email: String): Boolean {
return android.util.Patterns.EMAIL_ADDRESS.matcher(email).matches()
}
// With default params for click listener
fun View.setThrottleClickListener(
throttleTime: Long = 500L,
action: (View) -> Unit
) {
setOnClickListener {
isClickable = false
action(it)
postDelayed({ isClickable = true }, throttleTime)
}
}⚠️ Lưu ý quan trọng
[!TIP] Ưu tiên single-expression functions khi có thể:
// ✅ Clean fun double(x: Int) = x * 2 // ❌ Verbose cho logic đơn giản fun double(x: Int): Int { return x * 2 }
[!TIP] Dùng named arguments cho nhiều tham số:
// ❌ Khó đọc createUser("Alice", 25, "[email protected]", true, false, null) // ✅ Rõ ràng createUser( name = "Alice", age = 25, email = "[email protected]", isAdmin = true )
✅ Checklist - Tự kiểm tra
Sau bài học này, bạn có thể:
- Định nghĩa hàm với
fun - Sử dụng single-expression functions với
= - Sử dụng default parameters
- Sử dụng named arguments
- Hiểu
UnitvàNothingreturn types - Sử dụng
varargcho số lượng tham số không giới hạn
Tiếp theo: Lambda Expressions
Last updated on