Kotlin语法详解
Kotlin是一种静态类型的现代编程语言,具有简洁、安全和互操作性强的特点。下面我将从基础到高级详细解析Kotlin的核心语法。
一、基本语法结构
1. 程序入口
// 主函数
fun main() {
println("Hello, Kotlin!")
}
// 带参数的主函数
fun main(args: Array<String>) {
println("Args: ${args.joinToString()}")
}
2. 包声明与导入
package com.example.myapp
import kotlin.math.PI
import kotlin.math.sqrt as squareRoot // 别名导入
二、变量与常量
1. 变量声明
// 可变变量(var)
var count: Int = 10
count = 20 // 允许重新赋值
// 不可变变量(val)
val name: String = "Kotlin"
// name = "Java" // 编译错误,val不可重新赋值
// 类型推断
val message = "Hello" // 自动推断为String类型
val pi = 3.14 // 自动推断为Double
2. 延迟初始化
// lateinit用于非空类型的延迟初始化
lateinit var lateVariable: String
fun init() {
lateVariable = "Initialized"
println(lateVariable.length) // 使用前必须初始化
}
// 检查是否初始化
if (::lateVariable.isInitialized) {
println(lateVariable)
}
三、数据类型
1. 基本数据类型
// 数字类型
val byte: Byte = 1 // 8位
val short: Short = 2 // 16位
val int: Int = 3 // 32位
val long: Long = 4L // 64位
val float: Float = 5.0f // 32位
val double: Double = 6.0 // 64位
// 字符和布尔
val char: Char = 'A'
val bool: Boolean = true
// 字符串
val str: String = "Kotlin"
val rawStr = """
Line 1
Line 2
""".trimIndent()
2. 类型转换
val intNum = 100
val longNum = intNum.toLong() // 显式转换
val doubleNum = intNum.toDouble()
// 安全转换
val str = "123"
val num = str.toIntOrNull() // 失败返回null
3. 可空类型
var nullable: String? = null // 可空类型
var nonNullable: String = "text" // 非空类型
// 安全调用
val length = nullable?.length // 返回Int?
// Elvis操作符
val len = nullable?.length ?: 0 // 如果为null则返回0
// 非空断言(谨慎使用)
val forcedLen = nullable!!.length // 可能抛出NPE
四、控制结构
1. 条件表达式
// if表达式(可返回值)
val max = if (a > b) a else b
// when表达式(替代switch)
when (x) {
1 -> print("x == 1")
2, 3 -> print("x == 2 or 3")
in 4..10 -> print("4到10之间")
is String -> print("是字符串")
else -> print("其他")
}
// when作为表达式
val description = when {
x == 0 -> "zero"
x > 0 -> "positive"
else -> "negative"
}
2. 循环结构
// for循环
for (i in 1..5) print(i) // 1到5
for (i in 1 until 5) print(i) // 1到4
for (i in 5 downTo 1) print(i) // 5到1
for (i in 1..5 step 2) print(i) // 1,3,5
// 遍历集合
val list = listOf("a", "b", "c")
for (item in list) print(item)
for (index in list.indices) print(list[index])
for ((index, value) in list.withIndex()) {
println("$index: $value")
}
// while循环
while (x > 0) x--
do {
println(x)
x--
} while (x > 0)
五、函数
1. 函数定义
// 基本函数
fun sum(a: Int, b: Int): Int {
return a + b
}
// 表达式函数体
fun sum(a: Int, b: Int) = a + b
// 默认参数
fun greet(name: String = "World") = "Hello, $name!"
// 命名参数
greet(name = "Kotlin")
// 可变参数
fun printAll(vararg messages: String) {
for (m in messages) println(m)
}
printAll("Hello", "Kotlin", "World")
2. 高阶函数
// 函数作为参数
fun calculate(x: Int, y: Int, op: (Int, Int) -> Int): Int {
return op(x, y)
}
// Lambda表达式
val sum = calculate(5, 3) { a, b -> a + b }
val mul = calculate(5, 3) { a, b -> a * b }
// 内联函数(优化Lambda性能)
inline fun measureTime(block: () -> Unit) {
val start = System.currentTimeMillis()
block()
println("Time: ${System.currentTimeMillis() - start}ms")
}
六、类与对象
1. 类定义
// 主构造函数
class Person(val name: String, var age: Int) {
// 次构造函数
constructor(name: String) : this(name, 0)
// 初始化块
init {
println("Person initialized: $name")
}
// 属性
var nickname: String = ""
get() = field.uppercase()
set(value) {
field = value.lowercase()
}
// 方法
fun introduce() = "I'm $name, $age years old"
}
// 使用
val person = Person("Alice", 25)
person.age = 26
println(person.introduce())
2. 数据类
// 自动生成toString(), equals(), hashCode(), copy()
data class User(val id: Int, val name: String, val age: Int)
// 使用
val user1 = User(1, "Alice", 25)
val user2 = user1.copy(name = "Bob")
val (id, name, age) = user1 // 解构声明
3. 密封类
// 受限的类层次结构
sealed class Result {
data class Success(val data: String) : Result()
data class Error(val message: String) : Result()
}
fun handle(result: Result) = when(result) {
is Result.Success -> println("Success: ${result.data}")
is Result.Error -> println("Error: ${result.message}")
}
七、扩展
1. 扩展函数
// 为String添加扩展函数
fun String.addExclamation() = "$this!"
// 使用
println("Hello".addExclamation()) // 输出: Hello!
// 可空接收者
fun String?.orEmpty(): String = this ?: ""
val s: String? = null
println(s.orEmpty()) // 输出空字符串
2. 扩展属性
val String.lastChar: Char
get() = this[length - 1]
println("Kotlin".lastChar) // 输出: n
八、集合操作
1. 集合创建
// 不可变集合
val list = listOf("a", "b", "c")
val set = setOf(1, 2, 3)
val map = mapOf(1 to "one", 2 to "two")
// 可变集合
val mutableList = mutableListOf(1, 2, 3)
mutableList.add(4)
2. 常用操作
val numbers = listOf(1, 2, 3, 4, 5)
// 过滤
val evens = numbers.filter { it % 2 == 0 } // [2, 4]
// 映射
val squares = numbers.map { it * it } // [1, 4, 9, 16, 25]
// 排序
val sorted = numbers.sortedDescending() // [5, 4, 3, 2, 1]
// 分组
val grouped = numbers.groupBy {
if (it % 2 == 0) "even" else "odd"
} // {"odd"=[1,3,5], "even"=[2,4]}
// 聚合
val sum = numbers.reduce { acc, i -> acc + i } // 15
九、协程
1. 基本使用
import kotlinx.coroutines.*
// 启动协程
fun main() = runBlocking {
launch {
delay(1000L)
println("World!")
}
println("Hello,")
}
// 并发执行
suspend fun fetchData(): String {
delay(1000)
return "Data"
}
fun main() = runBlocking {
val deferred1 = async { fetchData() }
val deferred2 = async { fetchData() }
println("${deferred1.await()} and ${deferred2.await()}")
}
2. 协程上下文
fun main() = runBlocking {
// 指定调度器
launch(Dispatchers.IO) {
// 网络请求或文件操作
}
launch(Dispatchers.Default) {
// CPU密集型计算
}
launch(Dispatchers.Main) {
// UI更新(Android)
}
}
十、DSL构建
// HTML DSL示例
fun html(block: HTML.() -> Unit): HTML {
val html = HTML()
html.block()
return html
}
class HTML {
fun body(block: Body.() -> Unit) {
val body = Body()
body.block()
println(body)
}
}
class Body {
fun p(text: String) {
println("<p>$text</p>")
}
}
// 使用DSL
html {
body {
p("Hello, Kotlin DSL!")
}
}
Kotlin通过简洁的语法、强大的类型系统和丰富的特性,显著提高了开发效率和代码可读性。掌握这些语法细节将帮助你编写更优雅、更安全的Kotlin代码。