Skip to content

Kotlin 基础语法详解 📚

Android 面试必考 Kotlin 基础语法,包含变量声明、数据类型、控制流、区间等核心知识点


目录

  1. [变量声明(val/var)](#1-变量声明 valvar)
  2. 数据类型
  3. 字符串模板
  4. [条件表达式(if/when)](#4-条件表达式 ifwhen)
  5. [循环(for/while)](#5-循环 forwhile)
  6. 区间和数列
  7. 面试考点汇总

1. 变量声明(val/var)

1.1 val 与 var 的区别

Kotlin 提供了两种变量声明方式:

kotlin
// val - 只读变量(read-only),类似 Java 的 final
val name: String = "Kotlin"
// name = "Java"  // ❌ 编译错误:Val cannot be reassigned

// var - 可变变量(mutable),可以重新赋值
var age: Int = 25
age = 26  // ✅ 正确

// 类型推断(Type Inference)
val language = "Kotlin"  // 自动推断为 String
val version = 1.9        // 自动推断为 Double

1.2 最佳实践

kotlin
// ✅ 推荐:优先使用 val
val userName = "张三"
val maxCount = 100

// ⚠️ 仅在需要修改时使用 var
var currentIndex = 0
fun updateIndex() {
    currentIndex++  // 需要修改
}

// ✅ 延迟初始化(Lateinit)
class Presenter {
    private lateinit var view: View
    // lateinit 只能用于 var,不能用于 val
    // lateinit 不能用于基本数据类型(Int、Double 等)
    
    fun attachView(v: View) {
        view = v
    }
}

// ✅ 懒加载(Lazy)
val config: Config by lazy {
    // 第一次访问时执行,结果被缓存
    Config.loadFromFile()
}

1.3 val 的深层理解

kotlin
// val 是只读引用,不是不可变对象
val numbers = mutableListOf(1, 2, 3)
numbers.add(4)  // ✅ 可以修改集合内容
// numbers = mutableListOf(5, 6)  // ❌ 不能重新赋值

// 不可变集合
val immutableNumbers = listOf(1, 2, 3)
// immutableNumbers.add(4)  // ❌ 不可变集合没有 add 方法

// 自定义 getter
val area: Double
    get() = width * height  // 每次访问都重新计算

// 编译时常量(const)
const val API_URL = "https://api.example.com"
const val MAX_RETRIES = 3
// const 只能用于:String、基本类型、null
// const 必须在顶层或 object 中声明

1.4 常见错误

kotlin
// ❌ 错误:lateinit 用于基本类型
lateinit var count: Int  // 编译错误

// ✅ 正确:使用可空类型或包装类
lateinit var name: String  // ✅ String 是引用类型
var count: Int? = null     // ✅ 使用可空类型

// ❌ 错误:const 用于非常量
fun getUrl(): String {
    const val URL = "https://api.com"  // 编译错误
    return URL
}

// ✅ 正确:const 在顶层声明
const val URL = "https://api.com"

2. 数据类型

2.1 基本数据类型

Kotlin 的基本数据类型与 Java 类似,但所有类型都是对象:

kotlin
// 数值类型
val byteVal: Byte = 127          // 8 位有符号整数 (-128~127)
val shortVal: Short = 32767      // 16 位有符号整数
val intVal: Int = 2147483647     // 32 位有符号整数(最常用)
val longVal: Long = 9223372036854775807L  // 64 位有符号整数

val floatVal: Float = 3.14f      // 32 位浮点数
val doubleVal: Double = 3.14159  // 64 位浮点数(最常用)

// 字符和布尔
val charVal: Char = 'A'          // 单个字符
val boolVal: Boolean = true      // 布尔值

// 字符串
val stringVal: String = "Hello Kotlin"

2.2 类型转换

kotlin
// 显式转换(需要手动指定类型)
val intVal: Int = 100
val longVal: Long = intVal.toLong()
val doubleVal: Double = intVal.toDouble()
val stringVal: String = intVal.toString()

// 常见转换方法
val str = "123"
val num = str.toInt()      // 123
val num2 = str.toIntOrNull()  // 123,如果转换失败返回 null

// 不安全转换(可能抛异常)
val invalid = "abc".toInt()  // ❌ NumberFormatException

// 安全转换
val safe = "abc".toIntOrNull()  // null

// 自动类型提升
val result = 1 + 2L  // Int + Long = Long

2.3 类型转换完整示例

kotlin
fun convertTypes() {
    // 数值转换
    val byte: Byte = 10
    val int: Int = byte.toInt()      // Byte → Int
    val long: Long = byte.toLong()   // Byte → Long
    val float: Float = byte.toFloat() // Byte → Float
    val double: Double = byte.toDouble() // Byte → Double
    
    // 字符串转换
    val str = "42"
    val int1 = str.toInt()           // "42" → 42
    val int2 = str.toInt(16)         // "42" → 66 (16 进制)
    val long = str.toLong()          // "42" → 42L
    val double = str.toDouble()      // "42" → 42.0
    
    // 安全转换
    val safeInt = "abc".toIntOrNull()     // null
    val safeLong = "123".toLongOrNull()   // 123L
    val safeDouble = "3.14".toDoubleOrNull() // 3.14
    
    // 布尔转换
    val boolTrue = "true".toBoolean()     // true
    val boolFalse = "false".toBoolean()   // false
    val boolDefault = "invalid".toBoolean() // false
    
    // 字符转换
    val char = 'A'
    val intFromChar = char.code      // 65 (ASCII 码)
    val charFromInt = 66.toChar()    // 'B'
}

2.4 数组类型

kotlin
// 创建数组
val array1 = arrayOf(1, 2, 3)           // Array<Int>
val array2 = arrayOfNulls<String>(5)    // Array<String?>,长度为 5
val array3 = Array(5) { i -> i * 2 }    // [0, 2, 4, 6, 8]

// 基本类型数组(避免装箱,性能更好)
val intArray = intArrayOf(1, 2, 3)      // IntArray
val longArray = longArrayOf(1L, 2L, 3L) // LongArray
val doubleArray = doubleArrayOf(1.0, 2.0) // DoubleArray
val booleanArray = booleanArrayOf(true, false) // BooleanArray
val charArray = charArrayOf('a', 'b', 'c') // CharArray

// 数组操作
val arr = arrayOf(1, 2, 3, 4, 5)
println(arr.size)        // 5
println(arr[0])          // 1
arr[0] = 10              // 修改元素
println(arr.contains(2)) // true
println(arr.indexOf(3))  // 2

// 数组遍历
for (item in arr) {
    println(item)
}

for ((index, value) in arr.withIndex()) {
    println("Index $index: $value")
}

3. 字符串模板

3.1 基础语法

kotlin
val name = "Kotlin"
val version = 1.9

// $ 符号引用变量
val message = "Hello, $name!"  // "Hello, Kotlin!"

// ${} 表达式
val description = "$name version ${version}"  // "Kotlin version 1.9"

// 复杂表达式
val result = "The sum is ${2 + 3}"  // "The sum is 5"

// 调用方法
val upperName = "Hello, ${name.uppercase()}"  // "Hello, KOTLIN"

3.2 多行字符串

kotlin
// 三引号定义多行字符串
val html = """
    <html>
        <head>
            <title>Kotlin</title>
        </head>
        <body>
            <h1>Hello Kotlin</h1>
        </body>
    </html>
""".trimIndent()  // 去除每行前导空格

// trimMargin() 使用 | 作为边界标记
val sql = """
    |SELECT * FROM users
    |WHERE age > 18
    |ORDER BY name
""".trimMargin()

// 自定义边界标记
val xml = """
    <?xml version="1.0"?>
    <root>
        <item>Value</item>
    </root>
""".trimMargin("<?")

// 多行字符串中的模板
val user = "张三"
val age = 25
val json = """
    {
        "name": "$user",
        "age": $age,
        "adult": ${age >= 18}
    }
""".trimIndent()

3.3 字符串转义

kotlin
// 转义字符
val newline = "Line1\nLine2"      // 换行
val tab = "Col1\tCol2"            // 制表符
val quote = "He said \"Hello\""   // 双引号
val backslash = "C:\\Users\\Admin" // 反斜杠

// 多行字符串中不需要转义
val rawString = """
    Path: C:\Users\Admin
    Quote: "Hello World"
    Newline: 直接换行
"""

// 在多行字符串中使用 $ 符号
val price = "$100"  // ❌ 会被解析为模板
val price2 = "${'$'}100"  // ✅ "$100"
val price3 = """${'$'}100"""  // ✅ "$100"

3.4 字符串操作

kotlin
val text = "  Hello Kotlin  "

// 基本操作
println(text.length)           // 15
println(text.isEmpty())        // false
println(text.isBlank())        // false (有空白字符)
println("".isBlank())          // true

// 修剪
println(text.trim())           // "Hello Kotlin"
println(text.trimStart())      // "Hello Kotlin  "
println(text.trimEnd())        // "  Hello Kotlin"

// 大小写
println(text.lowercase())      // "  hello kotlin  "
println(text.uppercase())      // "  HELLO KOTLIN  "

// 子字符串
println(text.substring(2, 7))  // "Hello"
println(text.take(5))          // "  Hel"
println(text.drop(2))          // "Hello Kotlin  "

// 搜索
println(text.contains("Kotlin")) // true
println(text.startsWith("  "))   // true
println(text.endsWith("  "))     // true
println(text.indexOf("Kotlin"))  // 6

// 分割
val csv = "apple,banana,orange"
val fruits = csv.split(",")    // ["apple", "banana", "orange"]

val path = "usr/local/bin"
val dirs = path.split("/")     // ["usr", "local", "bin"]

// 替换
println(text.replace("Kotlin", "Java"))  // "  Hello Java  "
println(text.replace(Regex("\\s+"), " ")) // " Hello Kotlin "

// 连接
val joined = listOf("A", "B", "C").joinToString("-")  // "A-B-C"
val joined2 = listOf("X", "Y").joinToString(
    separator = ", ",
    prefix = "[",
    postfix = "]"
)  // "[X, Y]"

4. 条件表达式(if/when)

4.1 if 表达式

Kotlin 中 if 是表达式,可以返回值:

kotlin
// 传统用法
val max = if (a > b) a else b

// 带代码块
val max = if (a > b) {
    println("a is larger")
    a
} else {
    println("b is larger")
    b
}

// 替代三元运算符(Kotlin 没有 ?: 三元运算符)
val result = if (condition) "yes" else "no"

// 多层嵌套(不推荐)
val level = if (score >= 90) {
    "A"
} else if (score >= 80) {
    "B"
} else if (score >= 70) {
    "C"
} else {
    "D"
}

4.2 when 表达式

when 是 Kotlin 强大的条件表达式,替代 switch:

kotlin
val number = 3

// 基础用法
when (number) {
    1 -> println("One")
    2 -> println("Two")
    3 -> println("Three")
    else -> println("Other")  // 默认分支
}

// 多值匹配
when (number) {
    1, 2, 3 -> println("Small number")
    4, 5, 6 -> println("Medium number")
    else -> println("Large number")
}

// 范围匹配
when (number) {
    in 1..5 -> println("1 to 5")
    in 6..10 -> println("6 to 10")
    else -> println("Other")
}

// 类型检查
fun describe(obj: Any): String {
    return when (obj) {
        is Int -> "Integer: $obj"
        is String -> "String: ${obj.length} chars"
        is List<*> -> "List with ${obj.size} elements"
        else -> "Unknown type"
    }
}

// 无参数的 when(类似 if-else 链)
when {
    number > 0 -> println("Positive")
    number < 0 -> println("Negative")
    else -> println("Zero")
}

// when 作为表达式返回值
val description = when (number) {
    1 -> "One"
    2 -> "Two"
    else -> "Other"
}

4.3 when 高级用法

kotlin
// 匹配多个条件
fun checkValue(value: Int): String {
    return when (value) {
        in 1..10 -> "Small"
        in 11..100 -> "Medium"
        in 101..1000 -> "Large"
        else -> "Too big"
    }
}

// 匹配类型并智能转换
sealed class Result {
    data class Success(val data: String) : Result()
    data class Error(val message: String) : Result()
}

fun processResult(result: Result): String {
    return when (result) {
        is Result.Success -> "Data: ${result.data}"  // 智能转换,可直接访问 data
        is Result.Error -> "Error: ${result.message}"  // 智能转换,可直接访问 message
    }
}

// 匹配集合
fun checkList(list: List<Int>): String {
    return when {
        list.isEmpty() -> "Empty list"
        list.size == 1 -> "Single element: ${list[0]}"
        list.contains(0) -> "Contains zero"
        else -> "List with ${list.size} elements"
    }
}

// 复杂条件组合
fun categorize(age: Int, hasLicense: Boolean): String {
    return when {
        age < 18 -> "Minor"
        age >= 18 && hasLicense -> "Adult with license"
        age >= 18 && !hasLicense -> "Adult without license"
        else -> "Unknown"
    }
}

4.4 if vs when 选择指南

kotlin
// ✅ 使用 if 的场景
// 1. 简单的二元判断
val isAdult = age >= 18

// 2. 布尔条件
if (isLoggedIn && hasPermission) {
    showContent()
}

// 3. 空值检查
if (user != null) {
    processUser(user)
}

// ✅ 使用 when 的场景
// 1. 多值匹配
when (statusCode) {
    200 -> "Success"
    404 -> "Not Found"
    500 -> "Server Error"
    else -> "Unknown"
}

// 2. 类型分支
when (obj) {
    is String -> processString(obj)
    is Int -> processInt(obj)
    else -> processOther(obj)
}

// 3. 范围匹配
when (score) {
    in 90..100 -> "A"
    in 80..89 -> "B"
    in 70..79 -> "C"
    else -> "F"
}

5. 循环(for/while)

5.1 for 循环

kotlin
// 遍历数组
val array = arrayOf("A", "B", "C")
for (item in array) {
    println(item)
}

// 遍历集合
val list = listOf(1, 2, 3, 4, 5)
for (item in list) {
    println(item)
}

// 带索引遍历
for ((index, value) in list.withIndex()) {
    println("Index $index: $value")
}

// 使用区间
for (i in 1..5) {
    println(i)  // 1, 2, 3, 4, 5
}

// 半开区间(不包含结束值)
for (i in 1 until 5) {
    println(i)  // 1, 2, 3, 4
}

// 步长
for (i in 1..10 step 2) {
    println(i)  // 1, 3, 5, 7, 9
}

// 倒序
for (i in 5 downTo 1) {
    println(i)  // 5, 4, 3, 2, 1
}

// 倒序 + 步长
for (i in 10 downTo 1 step 2) {
    println(i)  // 10, 8, 6, 4, 2
}

// 遍历 Map
val map = mapOf("A" to 1, "B" to 2, "C" to 3)
for ((key, value) in map) {
    println("$key: $value")
}

// 遍历字符串
for (char in "Kotlin") {
    println(char)  // K, o, t, l, i, n
}

5.2 while 循环

kotlin
// while 循环
var count = 0
while (count < 5) {
    println(count)
    count++
}

// do-while 循环
var number = 0
do {
    println(number)
    number++
} while (number < 5)

// 实际应用场景
// 1. 重试机制
fun loadDataWithRetry(maxRetries: Int = 3) {
    var attempts = 0
    var success = false
    
    while (attempts < maxRetries && !success) {
        try {
            loadData()
            success = true
        } catch (e: Exception) {
            attempts++
            if (attempts >= maxRetries) throw e
            Thread.sleep(1000 * attempts)  // 指数退避
        }
    }
}

// 2. 用户输入验证
fun readValidNumber(): Int {
    var number: Int
    do {
        print("Enter a positive number: ")
        number = readLine()?.toIntOrNull() ?: -1
    } while (number <= 0)
    return number
}

5.3 循环控制

kotlin
// break - 跳出循环
for (i in 1..10) {
    if (i == 5) break
    println(i)  // 1, 2, 3, 4
}

// continue - 跳过本次迭代
for (i in 1..10) {
    if (i % 2 == 0) continue
    println(i)  // 1, 3, 5, 7, 9
}

// 标签(Label)- 跳出嵌套循环
outer@ for (i in 1..5) {
    for (j in 1..5) {
        if (i * j > 10) break@outer
        println("$i * $j = ${i * j}")
    }
}

// 标签 - 继续外层循环
search@ for (i in 0..array.size - 1) {
    for (j in 0..array[i].size - 1) {
        if (array[i][j] == target) {
            println("Found at [$i][$j]")
            continue@search
        }
    }
}

// 带返回值的循环
fun findFirstEven(numbers: List<Int>): Int? {
    for (num in numbers) {
        if (num % 2 == 0) return num
    }
    return null
}

5.4 函数式替代方案

kotlin
val numbers = listOf(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)

// 替代 for 循环的函数式方法
numbers.forEach { println(it) }  // 替代简单遍历

numbers.filter { it % 2 == 0 }   // 替代条件筛选
    .forEach { println(it) }

numbers.map { it * 2 }           // 替代转换
    .forEach { println(it) }

numbers.take(5)                  // 替代 break
    .forEach { println(it) }

numbers.dropWhile { it < 5 }     // 替代 continue
    .forEach { println(it) }

// 查找
numbers.find { it > 5 }          // 找到第一个符合条件的
numbers.count { it % 2 == 0 }    // 计数
numbers.any { it > 8 }           // 是否存在
numbers.all { it > 0 }           // 是否全部符合

6. 区间和数列

6.1 区间操作符

kotlin
// .. 闭区间(包含两端)
val range1 = 1..5      // 1, 2, 3, 4, 5
val range2 = 'a'..'z'  // 所有小写字母

// until 半开区间(不包含结束值)
val range3 = 1 until 5  // 1, 2, 3, 4

// downTo 倒序区间
val range4 = 5 downTo 1  // 5, 4, 3, 2, 1

// 区间判断
println(3 in 1..5)      // true
println(5 in 1 until 5) // false
println('m' in 'a'..'z') // true

// 区间作为集合
val range = 1..5
println(range.contains(3))  // true
println(range.isEmpty())    // false
println(range.first)        // 1
println(range.last)         // 5
println(range.count())      // 5

6.2 数列(Progressions)

kotlin
// 创建数列
val progression1 = 1..10 step 2   // 1, 3, 5, 7, 9
val progression2 = 10 downTo 1 step 2  // 10, 8, 6, 4, 2

// 数列遍历
for (i in 1..10 step 3) {
    println(i)  // 1, 4, 7, 10
}

// 数列转换为列表
val list = (1..5).toList()           // [1, 2, 3, 4, 5]
val set = (1..5).toSet()             // [1, 2, 3, 4, 5]
val array = (1..5).toIntArray()      // [1, 2, 3, 4, 5]

// 数列操作
val range = 1..10
println(range.sum())      // 55
println(range.average())  // 5.5
println(range.minOrNull()) // 1
println(range.maxOrNull()) // 10

// 生成数列
val squares = (1..5).map { it * it }  // [1, 4, 9, 16, 25]
val evens = (1..10).filter { it % 2 == 0 }  // [2, 4, 6, 8, 10]

6.3 字符区间

kotlin
// 字母区间
val letters = 'a'..'z'
val uppercase = 'A'..'Z'
val digits = '0'..'9'

// 使用示例
fun isLetter(char: Char): Boolean {
    return char in 'a'..'z' || char in 'A'..'Z'
}

fun isDigit(char: Char): Boolean {
    return char in '0'..'9'
}

fun isAlphanumeric(char: Char): Boolean {
    return char in 'a'..'z' || char in 'A'..'Z' || char in '0'..'9'
}

// 遍历字母表
for (letter in 'A'..'Z') {
    print("$letter ")
}
// A B C D E F G H I J K L M N O P Q R S T U V W X Y Z

// 生成字母列表
val alphabet = ('A'..'Z').toList()

6.4 自定义区间

kotlin
// 实现 Comparable 的自定义类型可以使用区间
class Version(val major: Int, val minor: Int) : Comparable<Version> {
    override fun compareTo(other: Version): Int {
        return compareValuesBy(this, other, { it.major }, { it.minor })
    }
    
    override fun toString() = "$major.$minor"
}

val v1 = Version(1, 0)
val v2 = Version(2, 0)
val v3 = Version(1, 5)

// 可以创建区间
val versionRange = v1..v2
println(v3 in versionRange)  // true

// 日期区间(使用 Java 时间 API)
import java.time.LocalDate

val start = LocalDate.of(2024, 1, 1)
val end = LocalDate.of(2024, 12, 31)
// 注意:LocalDate 没有实现 Comparable,需要手动处理

7. 面试考点汇总

7.1 基础问题

Q1: val 和 var 的区别是什么?

kotlin
// 答案要点:
// 1. val 是只读变量(read-only),一旦赋值不能修改
// 2. var 是可变变量(mutable),可以重新赋值
// 3. 优先使用 val,只在需要修改时使用 var
// 4. val 不等于 immutable,val 引用的对象内容可能可变

val numbers = mutableListOf(1, 2, 3)
numbers.add(4)  // ✅ 可以修改集合内容
// numbers = mutableListOf(5, 6)  // ❌ 不能重新赋值

Q2: Kotlin 有哪些基本数据类型?

kotlin
// 答案要点:
// 数值类型:Byte, Short, Int, Long, Float, Double
// 字符类型:Char
// 布尔类型:Boolean
// 所有类型都是对象,基本类型在需要时自动装箱

// 注意:Kotlin 没有 Java 的基本类型和包装类之分
// 编译到 JVM 时,会根据上下文选择使用基本类型或包装类

Q3: 如何进行类型转换?

kotlin
// 答案要点:
// 1. 使用 toXxx() 方法进行显式转换
// 2. 使用 toXxxOrNull() 进行安全转换
// 3. 基本类型数组使用 xxxArrayOf() 避免装箱

val str = "123"
val num = str.toInt()           // 123
val safeNum = "abc".toIntOrNull() // null

val intArray = intArrayOf(1, 2, 3)  // IntArray,避免装箱

7.2 进阶问题

Q4: if 和 when 的区别?什么时候用哪个?

kotlin
// 答案要点:
// 1. if 适合二元判断和布尔条件
// 2. when 适合多值匹配、类型检查、范围匹配
// 3. when 是 switch 的增强版,功能更强大
// 4. 两者都是表达式,可以返回值

// if 示例
val max = if (a > b) a else b

// when 示例
when (obj) {
    is String -> "String"
    is Int -> "Int"
    else -> "Other"
}

Q5: Kotlin 的 for 循环有哪些形式?

kotlin
// 答案要点:
// 1. 遍历集合/数组:for (item in collection)
// 2. 带索引:for ((index, value) in collection.withIndex())
// 3. 区间:for (i in 1..10)
// 4. 步长:for (i in 1..10 step 2)
// 5. 倒序:for (i in 10 downTo 1)
// 6. 半开区间:for (i in 1 until 10)

// 函数式替代:forEach, map, filter 等

Q6: 字符串模板有哪些用法?

kotlin
// 答案要点:
// 1. $variable 引用变量
// 2. ${expression} 引用表达式
// 3. 三引号定义多行字符串
// 4. trimIndent() 和 trimMargin() 处理缩进
// 5. 多行字符串中转义 $ 使用 ${'$'}

val name = "Kotlin"
val message = "Hello, $name!"
val result = "Sum: ${2 + 3}"

val html = """
    <html>
        <body>$message</body>
    </html>
""".trimIndent()

7.3 原理问题

Q7: const 和 val 的区别?

kotlin
// 答案要点:
// 1. const 是编译时常量,val 是运行时常量
// 2. const 只能用于 String 和基本类型
// 3. const 必须在顶层或 object 中声明
// 4. const 会被编译为 Java 的 static final
// 5. const 值在编译时确定,val 在运行时确定

const val API_URL = "https://api.com"  // 编译时常量
val timestamp = System.currentTimeMillis()  // 运行时常量

Q8: lateinit 和 by lazy 的区别?

kotlin
// 答案要点:
// 1. lateinit 用于 var,lazy 用于 val
// 2. lateinit 不能用于基本类型,lazy 可以
// 3. lateinit 在赋值前访问会抛异常
// 4. lazy 是线程安全的(默认 SYNCHRONIZED)
// 5. lateinit 由开发者保证初始化,lazy 自动初始化

lateinit var view: View  // 手动初始化
val config by lazy { Config() }  // 自动懒加载

Q9: Kotlin 基本类型与 Java 的区别?

kotlin
// 答案要点:
// 1. Kotlin 所有类型都是对象,没有基本类型和包装类之分
// 2. 编译到 JVM 时,根据上下文自动选择
// 3. 泛型中必须是包装类(List<Int> 编译为 List<Integer>)
// 4. 数组有专门的基本类型数组(IntArray 等)避免装箱
// 5. 性能敏感场景使用基本类型数组

val list: List<Int> = listOf(1, 2, 3)  // 装箱为 Integer
val array: IntArray = intArrayOf(1, 2, 3)  // 不装箱,性能更好

7.4 实战问题

Q10: 如何安全地处理字符串转数字?

kotlin
// 答案要点:
// 1. 使用 toIntOrNull() 等安全转换方法
// 2. 使用 try-catch 捕获 NumberFormatException
// 3. 使用 Elvis 操作符提供默认值
// 4. 验证输入范围

fun parseAge(input: String?): Int? {
    return input?.trim()?.toIntOrNull()
        ?.takeIf { it in 0..150 }
}

fun parseAgeOrDefault(input: String?, default: Int = 0): Int {
    return input?.trim()?.toIntOrNull() ?: default
}

Q11: 如何高效遍历大型集合?

kotlin
// 答案要点:
// 1. 使用序列(Sequence)避免中间集合
// 2. 使用 while 循环手动控制
// 3. 使用 take/takeWhile 限制数量
// 4. 使用 break 提前退出

// 序列(惰性求值)
val result = largeList.asSequence()
    .filter { it > 0 }
    .map { it * 2 }
    .take(10)
    .toList()

// 手动循环
var count = 0
for (item in largeList) {
    if (condition(item)) {
        process(item)
        if (++count >= 10) break
    }
}

最佳实践总结

✅ 推荐做法

kotlin
// 1. 优先使用 val
val name = "Kotlin"

// 2. 使用类型推断
val version = 1.9  // 而不是 val version: Double = 1.9

// 3. 使用字符串模板
val message = "Hello, $name!"

// 4. 使用 when 替代 switch
when (status) {
    SUCCESS -> handleSuccess()
    ERROR -> handleError()
}

// 5. 使用区间和数列
for (i in 1..10) { }

// 6. 使用安全转换
val num = str.toIntOrNull() ?: 0

❌ 避免做法

kotlin
// 1. 过度使用 var
var count = 0  // 如果可以,改用 val

// 2. 不必要的类型声明
val name: String = "Kotlin"  // 改为 val name = "Kotlin"

// 3. 字符串拼接
val message = "Hello, " + name + "!"  // 改为 "Hello, $name!"

// 4. 复杂的 if-else 链
if (x == 1) { } else if (x == 2) { }  // 改用 when

// 5. 不安全的类型转换
val num = str.toInt()  // 改为 str.toIntOrNull()

参考资料


最后更新:2026-04-14