Skip to content

条件语句

概述

Kotlin提供了强大的条件语句,包括if表达式和when表达式。与许多其他语言不同,Kotlin中的条件语句都是表达式,这意味着它们可以返回值,使代码更加简洁和函数式。

if 表达式

基本 if 语句

kotlin
fun main() {
    val score = 85
    
    // 基本if语句
    if (score >= 60) {
        println("及格了!")
    }
    
    // if-else语句
    if (score >= 90) {
        println("优秀")
    } else {
        println("良好")
    }
    
    // if-else if-else链
    if (score >= 90) {
        println("等级:A")
    } else if (score >= 80) {
        println("等级:B")
    } else if (score >= 70) {
        println("等级:C")
    } else if (score >= 60) {
        println("等级:D")
    } else {
        println("等级:F")
    }
}

if 作为表达式

kotlin
fun main() {
    val score = 85
    
    // if表达式返回值
    val grade = if (score >= 90) {
        "A"
    } else if (score >= 80) {
        "B"
    } else if (score >= 70) {
        "C"
    } else if (score >= 60) {
        "D"
    } else {
        "F"
    }
    
    println("成绩等级: $grade")
    
    // 简化的if表达式
    val status = if (score >= 60) "通过" else "不通过"
    println("考试状态: $status")
    
    // 复杂的if表达式
    val message = if (score >= 90) {
        val bonus = score - 90
        "优秀!额外奖励: $bonus 分"
    } else {
        val needed = 90 - score
        "还需要 $needed 分才能达到优秀"
    }
    
    println(message)
}

条件表达式的实际应用

kotlin
fun main() {
    // 空值检查
    val name: String? = "Alice"
    val displayName = if (name != null) name else "匿名用户"
    println("显示名称: $displayName")
    
    // 范围检查
    val temperature = 25
    val weather = if (temperature < 0) {
        "严寒"
    } else if (temperature < 10) {
        "寒冷"
    } else if (temperature < 20) {
        "凉爽"
    } else if (temperature < 30) {
        "温暖"
    } else {
        "炎热"
    }
    println("天气: $weather (${temperature}°C)")
    
    // 布尔逻辑
    val age = 20
    val hasLicense = true
    val canDrive = if (age >= 18 && hasLicense) {
        "可以开车"
    } else if (age < 18) {
        "年龄不够"
    } else {
        "需要驾照"
    }
    println("驾驶状态: $canDrive")
}

when 表达式

基本 when 表达式

kotlin
fun main() {
    val dayOfWeek = 3
    
    // 基本when表达式
    when (dayOfWeek) {
        1 -> println("星期一")
        2 -> println("星期二")
        3 -> println("星期三")
        4 -> println("星期四")
        5 -> println("星期五")
        6 -> println("星期六")
        7 -> println("星期日")
        else -> println("无效的日期")
    }
    
    // when作为表达式
    val dayName = when (dayOfWeek) {
        1 -> "Monday"
        2 -> "Tuesday"
        3 -> "Wednesday"
        4 -> "Thursday"
        5 -> "Friday"
        6 -> "Saturday"
        7 -> "Sunday"
        else -> "Invalid"
    }
    
    println("Day: $dayName")
}

when 的高级用法

kotlin
fun main() {
    val number = 15
    
    // 多个值匹配
    when (number) {
        1, 2, 3 -> println("小数字")
        4, 5, 6 -> println("中等数字")
        7, 8, 9 -> println("较大数字")
        else -> println("其他数字")
    }
    
    // 范围匹配
    when (number) {
        in 1..10 -> println("1到10之间")
        in 11..20 -> println("11到20之间")
        in 21..30 -> println("21到30之间")
        else -> println("超出范围")
    }
    
    // 类型检查
    val obj: Any = "Hello"
    when (obj) {
        is String -> println("字符串: $obj, 长度: ${obj.length}")
        is Int -> println("整数: $obj")
        is Boolean -> println("布尔值: $obj")
        else -> println("未知类型")
    }
    
    // 条件表达式
    val score = 85
    when {
        score >= 90 -> println("优秀")
        score >= 80 -> println("良好")
        score >= 70 -> println("中等")
        score >= 60 -> println("及格")
        else -> println("不及格")
    }
}

when 表达式的复杂应用

kotlin
enum class Color { RED, GREEN, BLUE, YELLOW, ORANGE, PURPLE }

fun mixColors(color1: Color, color2: Color): String {
    return when (setOf(color1, color2)) {
        setOf(Color.RED, Color.YELLOW) -> "橙色"
        setOf(Color.YELLOW, Color.BLUE) -> "绿色"
        setOf(Color.BLUE, Color.RED) -> "紫色"
        else -> "未知混合色"
    }
}

fun getColorInfo(color: Color): String {
    return when (color) {
        Color.RED -> {
            val wavelength = 700
            "红色 - 波长: ${wavelength}nm"
        }
        Color.GREEN -> {
            val wavelength = 550
            "绿色 - 波长: ${wavelength}nm"
        }
        Color.BLUE -> {
            val wavelength = 450
            "蓝色 - 波长: ${wavelength}nm"
        }
        else -> "其他颜色"
    }
}

fun main() {
    println("颜色混合:")
    println(mixColors(Color.RED, Color.YELLOW))
    println(mixColors(Color.BLUE, Color.YELLOW))
    
    println("\n颜色信息:")
    println(getColorInfo(Color.RED))
    println(getColorInfo(Color.GREEN))
}

嵌套条件语句

复杂的条件逻辑

kotlin
data class User(val name: String, val age: Int, val isVip: Boolean, val balance: Double)

fun checkAccess(user: User, requestedAmount: Double): String {
    return if (user.age >= 18) {
        if (user.isVip) {
            if (user.balance >= requestedAmount) {
                "VIP用户,交易批准"
            } else {
                "VIP用户,余额不足,但可以透支"
            }
        } else {
            if (user.balance >= requestedAmount) {
                "普通用户,交易批准"
            } else {
                "普通用户,余额不足"
            }
        }
    } else {
        "未成年用户,需要监护人同意"
    }
}

// 使用when重构嵌套if
fun checkAccessImproved(user: User, requestedAmount: Double): String {
    return when {
        user.age < 18 -> "未成年用户,需要监护人同意"
        user.isVip && user.balance >= requestedAmount -> "VIP用户,交易批准"
        user.isVip && user.balance < requestedAmount -> "VIP用户,余额不足,但可以透支"
        !user.isVip && user.balance >= requestedAmount -> "普通用户,交易批准"
        else -> "普通用户,余额不足"
    }
}

fun main() {
    val users = listOf(
        User("Alice", 25, true, 1000.0),
        User("Bob", 17, false, 500.0),
        User("Charlie", 30, false, 100.0),
        User("Diana", 28, true, 50.0)
    )
    
    val requestAmount = 200.0
    
    println("访问检查结果:")
    users.forEach { user ->
        val result = checkAccessImproved(user, requestAmount)
        println("${user.name}: $result")
    }
}

条件语句的最佳实践

1. 优先使用 when 而不是复杂的 if-else 链

kotlin
// 不推荐:复杂的if-else链
fun getGradeBad(score: Int): String {
    if (score >= 90) {
        return "A"
    } else if (score >= 80) {
        return "B"
    } else if (score >= 70) {
        return "C"
    } else if (score >= 60) {
        return "D"
    } else {
        return "F"
    }
}

// 推荐:使用when表达式
fun getGradeGood(score: Int): String = when {
    score >= 90 -> "A"
    score >= 80 -> "B"
    score >= 70 -> "C"
    score >= 60 -> "D"
    else -> "F"
}

fun main() {
    val score = 85
    println("成绩: ${getGradeGood(score)}")
}

2. 利用智能转换

kotlin
fun processValue(value: Any?) {
    when (value) {
        null -> println("值为空")
        is String -> {
            // 智能转换:value自动转换为String类型
            println("字符串值: '$value', 长度: ${value.length}")
            if (value.isNotEmpty()) {
                println("首字符: ${value[0]}")
            }
        }
        is Int -> {
            // 智能转换:value自动转换为Int类型
            println("整数值: $value")
            if (value > 0) {
                println("正数")
            } else if (value < 0) {
                println("负数")
            } else {
                println("零")
            }
        }
        is List<*> -> {
            // 智能转换:value自动转换为List类型
            println("列表值: $value, 大小: ${value.size}")
        }
        else -> println("未知类型: ${value::class.simpleName}")
    }
}

fun main() {
    val values = listOf("Hello", 42, null, listOf(1, 2, 3), 3.14)
    values.forEach { processValue(it) }
}

3. 使用表达式而不是语句

kotlin
// 不推荐:使用语句
fun getStatusBad(isOnline: Boolean, hasMessages: Boolean): String {
    var status: String
    if (isOnline) {
        if (hasMessages) {
            status = "在线 - 有新消息"
        } else {
            status = "在线"
        }
    } else {
        status = "离线"
    }
    return status
}

// 推荐:使用表达式
fun getStatusGood(isOnline: Boolean, hasMessages: Boolean): String {
    return when {
        isOnline && hasMessages -> "在线 - 有新消息"
        isOnline -> "在线"
        else -> "离线"
    }
}

// 更简洁的版本
fun getStatusBest(isOnline: Boolean, hasMessages: Boolean) = when {
    isOnline && hasMessages -> "在线 - 有新消息"
    isOnline -> "在线"
    else -> "离线"
}

fun main() {
    println(getStatusBest(true, true))
    println(getStatusBest(true, false))
    println(getStatusBest(false, false))
}

实际应用示例

用户权限系统

kotlin
enum class Role { ADMIN, MODERATOR, USER, GUEST }
enum class Permission { READ, WRITE, DELETE, MANAGE_USERS }

data class UserAccount(val name: String, val role: Role, val isActive: Boolean)

class PermissionChecker {
    fun hasPermission(user: UserAccount, permission: Permission): Boolean {
        if (!user.isActive) return false
        
        return when (user.role) {
            Role.ADMIN -> true  // 管理员有所有权限
            Role.MODERATOR -> when (permission) {
                Permission.READ, Permission.WRITE, Permission.DELETE -> true
                Permission.MANAGE_USERS -> false
            }
            Role.USER -> when (permission) {
                Permission.READ, Permission.WRITE -> true
                Permission.DELETE, Permission.MANAGE_USERS -> false
            }
            Role.GUEST -> permission == Permission.READ
        }
    }
    
    fun getAccessLevel(user: UserAccount): String {
        return when {
            !user.isActive -> "账户已禁用"
            user.role == Role.ADMIN -> "完全访问权限"
            user.role == Role.MODERATOR -> "管理员权限"
            user.role == Role.USER -> "标准用户权限"
            user.role == Role.GUEST -> "只读权限"
            else -> "未知权限级别"
        }
    }
}

fun main() {
    val users = listOf(
        UserAccount("Admin", Role.ADMIN, true),
        UserAccount("Moderator", Role.MODERATOR, true),
        UserAccount("User", Role.USER, true),
        UserAccount("Guest", Role.GUEST, true),
        UserAccount("Banned", Role.USER, false)
    )
    
    val checker = PermissionChecker()
    
    println("权限检查结果:")
    users.forEach { user ->
        println("\n${user.name} (${user.role}):")
        println("  访问级别: ${checker.getAccessLevel(user)}")
        Permission.values().forEach { permission ->
            val hasAccess = checker.hasPermission(user, permission)
            println("  $permission: ${if (hasAccess) "✓" else "✗"}")
        }
    }
}

计算器应用

kotlin
enum class Operation { ADD, SUBTRACT, MULTIPLY, DIVIDE, POWER, MODULO }

class Calculator {
    fun calculate(a: Double, b: Double, operation: Operation): Result<Double> {
        return when (operation) {
            Operation.ADD -> Result.success(a + b)
            Operation.SUBTRACT -> Result.success(a - b)
            Operation.MULTIPLY -> Result.success(a * b)
            Operation.DIVIDE -> {
                if (b != 0.0) {
                    Result.success(a / b)
                } else {
                    Result.failure(ArithmeticException("除数不能为零"))
                }
            }
            Operation.POWER -> Result.success(kotlin.math.pow(a, b))
            Operation.MODULO -> {
                if (b != 0.0) {
                    Result.success(a % b)
                } else {
                    Result.failure(ArithmeticException("模数不能为零"))
                }
            }
        }
    }
    
    fun getOperationSymbol(operation: Operation): String = when (operation) {
        Operation.ADD -> "+"
        Operation.SUBTRACT -> "-"
        Operation.MULTIPLY -> "*"
        Operation.DIVIDE -> "/"
        Operation.POWER -> "^"
        Operation.MODULO -> "%"
    }
}

fun main() {
    val calculator = Calculator()
    val testCases = listOf(
        Triple(10.0, 5.0, Operation.ADD),
        Triple(10.0, 3.0, Operation.SUBTRACT),
        Triple(4.0, 3.0, Operation.MULTIPLY),
        Triple(15.0, 3.0, Operation.DIVIDE),
        Triple(15.0, 0.0, Operation.DIVIDE),  // 错误情况
        Triple(2.0, 3.0, Operation.POWER),
        Triple(17.0, 5.0, Operation.MODULO)
    )
    
    println("计算器测试:")
    testCases.forEach { (a, b, op) ->
        val symbol = calculator.getOperationSymbol(op)
        val result = calculator.calculate(a, b, op)
        
        when {
            result.isSuccess -> {
                val value = result.getOrNull()
                println("$a $symbol $b = $value")
            }
            result.isFailure -> {
                val error = result.exceptionOrNull()
                println("$a $symbol $b = 错误: ${error?.message}")
            }
        }
    }
}

性能考虑

when 表达式的优化

kotlin
// 编译器会优化when表达式
fun optimizedWhen(value: Int): String {
    return when (value) {
        1, 2, 3, 4, 5 -> "小数字"  // 编译器可能生成跳转表
        in 6..10 -> "中等数字"
        in 11..100 -> "大数字"
        else -> "很大的数字"
    }
}

// 对于枚举,编译器会生成高效的代码
enum class Status { PENDING, PROCESSING, COMPLETED, FAILED }

fun getStatusMessage(status: Status): String = when (status) {
    Status.PENDING -> "等待处理"
    Status.PROCESSING -> "正在处理"
    Status.COMPLETED -> "已完成"
    Status.FAILED -> "处理失败"
}

下一步

掌握了条件语句后,让我们学习Kotlin中的循环语句,包括for循环、while循环等。

下一章: 循环语句

练习题

  1. 创建一个成绩评定系统,根据分数给出等级和评语
  2. 实现一个简单的状态机,使用when表达式处理状态转换
  3. 编写一个函数来判断年份是否为闰年
  4. 设计一个游戏角色职业系统,根据职业分配不同的技能
  5. 创建一个智能推荐系统,根据用户偏好推荐内容

本站内容仅供学习和研究使用。