Bỏ qua để đến nội dung

⚡ Hàm (Function)

🎯 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.


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!
}

fun functionName(param1: Type1, param2: Type2): ReturnType {
// body
return value
}
fun printMessage(message: String): Unit {
println(message)
}
// Unit có thể bỏ qua
fun printMessage(message: String) {
println(message)
}

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!"

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!
}

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

Phần tiêu đề “📦 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
}

fun multiply(a: Int, b: Int): Int {
return a * b
}
fun multiply(a: Int, b: Int) = a * b
fun fail(message: String): Nothing {
throw IllegalStateException(message)
}
fun validateAge(age: Int): Int {
if (age < 0) fail("Age cannot be negative")
return age
}

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
}

// 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)
}
}


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 UnitNothing return types
  • Sử dụng vararg cho số lượng tham số không giới hạn

Tiếp theo: Lambda Expressions