后端开发

Kotlin 完全教程

现代化的 JVM 语言,简洁、安全、高效

Kotlin 完全教程

Kotlin 是由 JetBrains 开发的现代编程语言,运行在 JVM 上,也可以编译成 JavaScript 或原生代码。它简洁、安全、与 Java 100% 互操作。

为什么选择 Kotlin?

  • 简洁:比 Java 代码量减少 40%
  • 安全:空安全设计,避免 NullPointerException
  • 互操作:与 Java 无缝集成
  • 现代化:支持函数式编程、协程等特性
  • 官方支持:Android 官方推荐语言

环境搭建

安装 Kotlin

# macOS (使用 Homebrew)
brew install kotlin

# 或使用 SDKMAN
sdk install kotlin

创建项目

使用 Gradle

mkdir my-kotlin-app
cd my-kotlin-app
gradle init --type kotlin-application

使用 IntelliJ IDEA(推荐):

  1. File → New → Project
  2. 选择 Kotlin
  3. 选择构建工具(Gradle 或 Maven)

基础语法

Hello World

fun main() {
    println("Hello, Kotlin!")
}

变量声明

// val:不可变变量(推荐)
val name: String = "张三"
val age = 25  // 类型推断

// var:可变变量
var count = 0
count = 1

// 常量
const val PI = 3.14159

基本类型

// 数字
val byte: Byte = 127
val short: Short = 32767
val int: Int = 2147483647
val long: Long = 9223372036854775807L
val float: Float = 3.14f
val double: Double = 3.14159

// 字符和字符串
val char: Char = 'A'
val string: String = "Hello"

// 布尔
val isTrue: Boolean = true

// 数组
val numbers = arrayOf(1, 2, 3, 4, 5)
val strings = arrayOf("a", "b", "c")

字符串模板

val name = "Kotlin"
val version = 1.9

println("Welcome to $name $version")
println("2 + 2 = ${2 + 2}")

// 多行字符串
val text = """
    |第一行
    |第二行
    |第三行
""".trimMargin()

条件表达式

// if 表达式
val max = if (a > b) a else b

// when 表达式(类似 switch)
val result = when (x) {
    1 -> "one"
    2 -> "two"
    in 3..10 -> "3 to 10"
    else -> "other"
}

// when 不带参数
when {
    x < 0 -> println("negative")
    x == 0 -> println("zero")
    else -> println("positive")
}

循环

// for 循环
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 5 downTo 1 step 2) {
    println(i)  // 5, 3, 1
}

// 遍历集合
val items = listOf("apple", "banana", "cherry")
for (item in items) {
    println(item)
}

// while 循环
var x = 5
while (x > 0) {
    println(x)
    x--
}

函数

基本函数

// 标准函数
fun add(a: Int, b: Int): Int {
    return a + b
}

// 单表达式函数
fun multiply(a: Int, b: Int) = a * b

// 默认参数
fun greet(name: String = "Guest") {
    println("Hello, $name!")
}

// 命名参数
fun createUser(name: String, age: Int, email: String) {
    // ...
}
createUser(name = "张三", email = "zhangsan@example.com", age = 25)

// 可变参数
fun sum(vararg numbers: Int): Int {
    return numbers.sum()
}
sum(1, 2, 3, 4, 5)

高阶函数

// 函数作为参数
fun calculate(a: Int, b: Int, operation: (Int, Int) -> Int): Int {
    return operation(a, b)
}

val result = calculate(5, 3) { x, y -> x + y }

// 函数作为返回值
fun makeMultiplier(factor: Int): (Int) -> Int {
    return { number -> number * factor }
}

val double = makeMultiplier(2)
println(double(5))  // 10

Lambda 表达式

// 基本 lambda
val sum = { a: Int, b: Int -> a + b }

// 集合操作
val numbers = listOf(1, 2, 3, 4, 5)

val doubled = numbers.map { it * 2 }
val evens = numbers.filter { it % 2 == 0 }
val sum = numbers.reduce { acc, n -> acc + n }

// it:单参数 lambda 的隐式名称
val squared = numbers.map { it * it }

类和对象

基本类

// 主构造函数
class Person(val name: String, var age: Int) {
    // 初始化块
    init {
        println("Person created: $name")
    }

    // 成员函数
    fun greet() {
        println("Hello, I'm $name")
    }
}

// 使用
val person = Person("张三", 25)
person.greet()

数据类

// 自动生成 equals、hashCode、toString、copy
data class User(
    val id: Int,
    val name: String,
    val email: String
)

val user1 = User(1, "张三", "zhangsan@example.com")
val user2 = user1.copy(name = "李四")

println(user1)  // User(id=1, name=张三, email=zhangsan@example.com)

继承

// 基类(必须用 open 标记)
open class Animal(val name: String) {
    open fun makeSound() {
        println("Some sound")
    }
}

// 派生类
class Dog(name: String) : Animal(name) {
    override fun makeSound() {
        println("Woof!")
    }
}

// 抽象类
abstract class Shape {
    abstract fun area(): Double
}

class Circle(val radius: Double) : Shape() {
    override fun area() = Math.PI * radius * radius
}

接口

interface Clickable {
    fun click()
    fun showOff() = println("I'm clickable!")  // 默认实现
}

class Button : Clickable {
    override fun click() {
        println("Button clicked")
    }
}

对象声明和伴生对象

// 单例对象
object DatabaseConfig {
    val url = "jdbc:mysql://localhost:3306/db"
    fun connect() {
        println("Connecting to $url")
    }
}

// 伴生对象(类似 Java 的静态成员)
class User(val name: String) {
    companion object {
        const val TABLE_NAME = "users"

        fun create(name: String): User {
            return User(name)
        }
    }
}

val user = User.create("张三")

空安全

Kotlin 的类型系统区分可空和不可空引用。

// 不可空类型
var name: String = "Kotlin"
// name = null  // 编译错误

// 可空类型
var nullableName: String? = "Kotlin"
nullableName = null  // OK

// 安全调用
val length = nullableName?.length

// Elvis 操作符
val length = nullableName?.length ?: 0

// 非空断言(不推荐)
val length = nullableName!!.length

// 安全转换
val number: Int? = value as? Int

// let 函数
nullableName?.let {
    println("Name is $it")
}

集合

不可变集合

// List
val numbers = listOf(1, 2, 3, 4, 5)

// Set
val uniqueNumbers = setOf(1, 2, 3, 3, 4)  // [1, 2, 3, 4]

// Map
val map = mapOf(
    "name" to "张三",
    "age" to 25
)

可变集合

// MutableList
val numbers = mutableListOf(1, 2, 3)
numbers.add(4)
numbers.remove(1)

// MutableSet
val set = mutableSetOf(1, 2, 3)
set.add(4)

// MutableMap
val map = mutableMapOf("name" to "张三")
map["age"] = 25

集合操作

val numbers = listOf(1, 2, 3, 4, 5)

// 转换
val doubled = numbers.map { it * 2 }
val strings = numbers.map { "Number $it" }

// 过滤
val evens = numbers.filter { it % 2 == 0 }
val odds = numbers.filterNot { it % 2 == 0 }

// 查找
val first = numbers.first { it > 3 }  // 4
val firstOrNull = numbers.firstOrNull { it > 10 }  // null

// 聚合
val sum = numbers.sum()
val max = numbers.maxOrNull()
val average = numbers.average()

// 分组
val grouped = numbers.groupBy { it % 2 == 0 }
// {false=[1, 3, 5], true=[2, 4]}

// 排序
val sorted = numbers.sortedDescending()

// 去重
val unique = listOf(1, 2, 2, 3, 3, 3).distinct()

协程

Kotlin 协程提供了简洁的异步编程方式。

基础使用

import kotlinx.coroutines.*

fun main() = runBlocking {
    launch {
        delay(1000L)
        println("World!")
    }
    println("Hello,")
}

挂起函数

suspend fun fetchUser(id: Int): User {
    delay(1000)  // 模拟网络请求
    return User(id, "张三")
}

fun main() = runBlocking {
    val user = fetchUser(1)
    println(user)
}

并发执行

fun main() = runBlocking {
    val time = measureTimeMillis {
        val one = async { fetchData1() }
        val two = async { fetchData2() }
        println("Result: ${one.await()} ${two.await()}")
    }
    println("Completed in $time ms")
}

suspend fun fetchData1(): String {
    delay(1000)
    return "Data1"
}

suspend fun fetchData2(): String {
    delay(1000)
    return "Data2"
}

协程作用域

class MyViewModel : ViewModel() {
    private val viewModelScope = CoroutineScope(Dispatchers.Main)

    fun loadData() {
        viewModelScope.launch {
            try {
                val data = withContext(Dispatchers.IO) {
                    fetchDataFromNetwork()
                }
                updateUI(data)
            } catch (e: Exception) {
                handleError(e)
            }
        }
    }
}

扩展函数

为现有类添加新功能,无需继承。

// 扩展函数
fun String.removeSpaces(): String {
    return this.replace(" ", "")
}

val text = "Hello World"
println(text.removeSpaces())  // "HelloWorld"

// 扩展属性
val String.lastChar: Char
    get() = this[length - 1]

println("Kotlin".lastChar)  // 'n'

委托

类委托

interface Base {
    fun print()
}

class BaseImpl(val x: Int) : Base {
    override fun print() { println(x) }
}

class Derived(b: Base) : Base by b

val base = BaseImpl(10)
Derived(base).print()  // 10

属性委托

// lazy:延迟初始化
val lazyValue: String by lazy {
    println("Computed!")
    "Hello"
}

// observable:观察属性变化
var name: String by Delegates.observable("Initial") { prop, old, new ->
    println("$old -> $new")
}

实战示例

REST API(使用 Ktor)

import io.ktor.server.application.*
import io.ktor.server.engine.*
import io.ktor.server.netty.*
import io.ktor.server.response.*
import io.ktor.server.routing.*

fun main() {
    embeddedServer(Netty, port = 8080) {
        routing {
            get("/") {
                call.respondText("Hello, Kotlin!")
            }

            get("/users/{id}") {
                val id = call.parameters["id"]
                call.respondText("User $id")
            }
        }
    }.start(wait = true)
}

数据库操作(使用 Exposed)

import org.jetbrains.exposed.sql.*
import org.jetbrains.exposed.sql.transactions.transaction

object Users : Table() {
    val id = integer("id").autoIncrement()
    val name = varchar("name", 50)
    val email = varchar("email", 100)

    override val primaryKey = PrimaryKey(id)
}

fun main() {
    Database.connect("jdbc:h2:mem:test", driver = "org.h2.Driver")

    transaction {
        SchemaUtils.create(Users)

        // 插入
        Users.insert {
            it[name] = "张三"
            it[email] = "zhangsan@example.com"
        }

        // 查询
        Users.selectAll().forEach {
            println("${it[Users.name]}: ${it[Users.email]}")
        }
    }
}

最佳实践

1. 优先使用 val

// 好
val name = "Kotlin"

// 避免
var name = "Kotlin"

2. 使用数据类

// 好
data class User(val id: Int, val name: String)

// 避免
class User(val id: Int, val name: String)

3. 利用空安全

// 好
val length = name?.length ?: 0

// 避免
val length = if (name != null) name.length else 0

4. 使用扩展函数

// 好
fun String.isEmail() = this.contains("@")

// 避免
fun isEmail(str: String) = str.contains("@")

5. 使用作用域函数

// let
val result = value?.let {
    transform(it)
}

// apply
val person = Person().apply {
    name = "张三"
    age = 25
}

// also
val numbers = mutableListOf(1, 2, 3).also {
    println("Before: $it")
}.add(4)

// run
val result = service.run {
    connect()
    fetchData()
}

// with
with(person) {
    println(name)
    println(age)
}

常用库推荐

  • Web 框架:Ktor, Spring Boot
  • 数据库:Exposed, Ktorm
  • 序列化:kotlinx.serialization
  • HTTP 客户端:Ktor Client, OkHttp
  • 测试:JUnit 5, Kotest, MockK
  • 依赖注入:Koin, Kodein

总结

Kotlin 是现代化的 JVM 语言,特别适合:

  • Android 应用开发
  • 后端服务开发
  • 多平台项目(Kotlin Multiplatform)
  • 从 Java 迁移的项目

开始使用 Kotlin,享受简洁、安全、高效的编程体验!

参考资源