7.5 KiB
7.5 KiB
Kotlin基础
目录
基本语法
变量声明
// 可变变量
var name: String = "John"
name = "Jane"
// 不可变变量
val age: Int = 25
// age = 26 // 编译错误
// 类型推断
var count = 10 // 自动推断为 Int
var message = "Hello" // 自动推断为 String
函数定义
// 普通函数
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")
}
// 命名参数
greet(name = "John")
控制流
// if 表达式
val max = if (a > b) a else b
// when 表达式(类似 switch)
when (x) {
1 -> println("One")
2 -> println("Two")
else -> println("Other")
}
// for 循环
for (i in 1..10) {
println(i)
}
for (item in list) {
println(item)
}
// while 循环
while (condition) {
// 代码
}
空安全
可空类型
// 可空类型
var name: String? = null
name = "John"
// 安全调用
val length = name?.length // 如果 name 为 null,返回 null
// Elvis 操作符
val length2 = name?.length ?: 0 // 如果 name 为 null,返回 0
// 非空断言
val length3 = name!!.length // 如果 name 为 null,抛出异常
空安全操作
// 安全调用链
val length = user?.address?.street?.length
// let 函数
name?.let {
println(it.length)
}
// 类型检查
if (obj is String) {
println(obj.length) // 自动转换为 String
}
扩展函数
扩展函数定义
// 为 String 添加扩展函数
fun String.removeSpaces(): String {
return this.replace(" ", "")
}
// 使用
val text = "Hello World"
val result = text.removeSpaces() // "HelloWorld"
// 为 View 添加扩展函数
fun View.show() {
this.visibility = View.VISIBLE
}
fun View.hide() {
this.visibility = View.GONE
}
扩展属性
// 扩展属性
val String.lastChar: Char
get() = this[this.length - 1]
// 使用
val text = "Hello"
val last = text.lastChar // 'o'
数据类
数据类定义
// 数据类:自动生成 equals、hashCode、toString、copy 等方法
data class User(
val id: Int,
val name: String,
val email: String
)
// 使用
val user = User(1, "John", "john@example.com")
println(user) // User(id=1, name=John, email=john@example.com)
// 复制
val user2 = user.copy(name = "Jane")
// 解构
val (id, name, email) = user
数据类限制
// 数据类限制
// 1. 主构造函数至少有一个参数
// 2. 主构造函数参数必须标记为 val 或 var
// 3. 数据类不能是抽象、开放、密封或内部类
密封类
密封类定义
// 密封类:限制子类只能在同一个文件中
sealed class Result<out T> {
data class Success<T>(val data: T) : Result<T>()
data class Error(val message: String) : Result<Nothing>()
object Loading : Result<Nothing>()
}
// 使用
fun handleResult(result: Result<String>) {
when (result) {
is Result.Success -> println(result.data)
is Result.Error -> println(result.message)
is Result.Loading -> println("Loading...")
}
}
协程基础
协程创建
// 启动协程
GlobalScope.launch {
delay(1000)
println("Hello from coroutine")
}
// 使用 runBlocking
runBlocking {
delay(1000)
println("Hello")
}
// 使用 CoroutineScope
val scope = CoroutineScope(Dispatchers.Main)
scope.launch {
delay(1000)
println("Hello")
}
协程作用域
// CoroutineScope
class MyActivity : AppCompatActivity(), CoroutineScope by MainScope() {
override fun onDestroy() {
cancel() // 取消所有协程
super.onDestroy()
}
}
// viewModelScope(ViewModel)
class MyViewModel : ViewModel() {
fun loadData() {
viewModelScope.launch {
// 协程代码
}
}
}
// lifecycleScope(LifecycleOwner)
lifecycleScope.launch {
// 协程代码
}
协程上下文
// Dispatchers
launch(Dispatchers.Main) {
// 主线程
}
launch(Dispatchers.IO) {
// IO 线程
}
launch(Dispatchers.Default) {
// 默认线程池
}
委托
类委托
// 类委托:将接口实现委托给另一个对象
interface Base {
fun print()
}
class BaseImpl(val x: Int) : Base {
override fun print() {
println(x)
}
}
class Derived(b: Base) : Base by b
// 使用
val b = BaseImpl(10)
val derived = Derived(b)
derived.print() // 10
属性委托
// lazy 委托:延迟初始化
val lazyValue: String by lazy {
println("Computed!")
"Hello"
}
// 使用
println(lazyValue) // 第一次访问时计算
println(lazyValue) // 直接返回缓存值
// observable 委托:监听属性变化
var name: String by Delegates.observable("Initial") { prop, old, new ->
println("$old -> $new")
}
高阶函数
高阶函数定义
// 高阶函数:接受函数作为参数或返回函数
fun operation(x: Int, y: Int, op: (Int, Int) -> Int): Int {
return op(x, y)
}
// 使用
val result = operation(5, 3) { a, b -> a + b } // 8
val result2 = operation(5, 3) { a, b -> a * b } // 15
常用高阶函数
val list = listOf(1, 2, 3, 4, 5)
// map:转换
val doubled = list.map { it * 2 } // [2, 4, 6, 8, 10]
// filter:过滤
val evens = list.filter { it % 2 == 0 } // [2, 4]
// reduce:累积
val sum = list.reduce { acc, i -> acc + i } // 15
// forEach:遍历
list.forEach { println(it) }
Lambda表达式
Lambda 语法
// Lambda 表达式
val sum = { x: Int, y: Int -> x + y }
println(sum(1, 2)) // 3
// 简化语法
val list = listOf(1, 2, 3)
list.forEach { println(it) }
// it:单个参数的隐式名称
list.map { it * 2 }
Lambda 与集合
val numbers = listOf(1, 2, 3, 4, 5)
// map
val squares = numbers.map { it * it } // [1, 4, 9, 16, 25]
// filter
val evens = numbers.filter { it % 2 == 0 } // [2, 4]
// find
val firstEven = numbers.find { it % 2 == 0 } // 2
// any / all
val hasEven = numbers.any { it % 2 == 0 } // true
val allEven = numbers.all { it % 2 == 0 } // false
面试常见问题
Q1: Kotlin 和 Java 的区别?
答案:
- 空安全:Kotlin 有可空类型,编译时检查
- 简洁性:Kotlin 代码更简洁
- 扩展函数:可以为类添加新方法
- 数据类:自动生成常用方法
- 协程:轻量级线程
Q2: Kotlin 空安全机制?
答案:
- 可空类型:
String?表示可能为 null - 安全调用:
?.操作符 - Elvis 操作符:
?:提供默认值 - 非空断言:
!!强制非空
Q3: 扩展函数的作用?
答案:
- 为现有类添加新方法
- 不修改原类代码
- 提高代码复用性
- 使代码更易读
Q4: 数据类的特点?
答案:
- 自动生成
equals、hashCode、toString、copy方法 - 支持解构声明
- 简化数据模型定义
Q5: 协程的优势?
答案:
- 轻量级:比线程更轻量
- 挂起恢复:可以挂起和恢复
- 结构化并发:自动管理生命周期
- 简化异步代码
最后更新:2024年