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(推荐):
- File → New → Project
- 选择 Kotlin
- 选择构建工具(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)) // 10Lambda 表达式
// 基本 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 04. 使用扩展函数
// 好
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,享受简洁、安全、高效的编程体验!
