From c6b44364c22f08e104783343c6b10a27b4111cbc Mon Sep 17 00:00:00 2001
From: SOR <3272194354@qq.com>
Date: Sat, 19 Sep 2026 16:46:40 +0800
Subject: [PATCH] =?UTF-8?q?=E5=A4=A7=E9=83=A8=E5=88=86=E7=9A=84=E6=B7=B1?=
=?UTF-8?q?=E5=85=A5=20Kotlin?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
Learning/成为Kotlin超人.md | 8 +-
Learning/深入Kotlin.md | 288 ++++++++++++++++++++++++++++++++++---
2 files changed, 276 insertions(+), 20 deletions(-)
diff --git a/Learning/成为Kotlin超人.md b/Learning/成为Kotlin超人.md
index d56512a..580e4e0 100644
--- a/Learning/成为Kotlin超人.md
+++ b/Learning/成为Kotlin超人.md
@@ -3,9 +3,13 @@
> 来到这里,我不再会给出详尽的用法。
> 以你的实力,只要我指出在什么时候应该使用什么就够了。
-## JSON 序列化
+## 在哪里找到最全面的 Kotlin 文档
-## 时间
+虽然 [深入 Kotlin](./深入Kotlin.md) 中已经讲了很多内容,但其实我仍有删减。
+
+[官方文档](https://book.kotlincn.net/text/d-concepts.html)
+
+## JSON 序列化
## Kotlin 协程
diff --git a/Learning/深入Kotlin.md b/Learning/深入Kotlin.md
index e3d5c77..6bd7c43 100644
--- a/Learning/深入Kotlin.md
+++ b/Learning/深入Kotlin.md
@@ -37,6 +37,8 @@ class MyClass private constructor( // 非私有时,constructor 可省
}
```
+这是最方便的方法,我如果不用私有构造函数基本就是这样写,再使用默认值配合。
+
2. 写在类定义之内
```kotlin
@@ -62,7 +64,7 @@ class MyClass(
) {
constructor(
val amount: Int
- ) : this(null, amount)
+ ) : this("Unknown", amount)
// something else
}
```
@@ -72,28 +74,136 @@ class MyClass(
定义方法:
```kotlin
+class MyClass() {
companion object {}
+}
```
-它的使用和 object 完全一致,用于替代 Java 中的 static 修饰符。是一个非常方便的东西。
+它的使用和 object 完全一致,用于替代 Java 中的 static 修饰符,是一个非常方便的东西。可以省去工厂类,直接在伴生对象里定义工厂函数。
+
+### 类中类
+
+#### 嵌套类
+
+你可以在类中定义任何类,它们的调用需要带上外层类,或者在 import 中多写一层外层类名:
+
+```kotlin
+class OuterClass() {
+ class InnerClass() {}
+}
+
+// 如果只 import 外层类
+import pack.age.OuterClass
+
+val a = OuterClass.InnerClass()
+
+// 如果想 import 内层类
+import pack.age.OuterClass.InnerClass
+
+val a = InnerClass()
+```
+
+#### 内部类
+
+内部类的定义需要在 class 前添加一个 `inner` 关键字。
+
+内部类的特点是:它可以使用外部类的任意属性,包括私有的。有时会很方便。
+
+如果出现同名属性可以使用标签来指明是哪一个类的属性:
+
+```kotlin
+class MainActivity {
+ fun showToast() {
+ println("display")
+ }
+
+ inner class MyButton {
+ fun showToast() {}
+
+ fun setOnClickListener() {
+ this@MainActivity.showToast()
+ } // @ 后面写类名,用法与 this 一致
+ }
+}
+```
### 类继承细节
+在 Kotlin 中,一个类最多只能直接继承一个类,但可以继承任意多个接口
+
+#### 子类
+
+如果类被继承,其中的类中类不会有任何影响,子类不含有类中类的任何信息。
+
+Kotlin 中所有的类,成员变量,函数都是不可被继承,不可被重写的。如果需要继承 / 重写,只要在定义的开头加上 `open`。而接口 interface 的任意属性包括它自己默认就是 open 的。
+
+在一个类的子类中可以使用它的父类(超类)的任意属性,用 `super` 代指,用法与 this 一致。
+
+```kotlin
+class FilledRectangle : Rectangle() {
+ override fun draw() {
+ super.draw()
+ println("Filling the rectangle")
+ }
+
+ val fillColor: String get() = super.borderColor
+}
+```
+
+这里,父类名后括号的含义是指,子类使用与父类一致的构造函数,且没有参数。
+
+如果一个类继承的类 / 接口中含有重名的属性,那么子类必须重写。你可以在子类中以这种方式使用来自不同定义的属性:
+
+```kotlin
+open class Rectangle {
+ open fun draw() {}
+}
+
+interface Polygon { // interface 默认 open
+ fun draw() {}
+}
+
+class Square() : Rectangle(), Polygon {
+ override fun draw() {
+ super.draw() // 调用 Rectangle.draw()
+ super.draw() // 调用 Polygon.draw()
+ }
+}
+```
+
+#### 接口
+
+接口
+
+#### 抽象类
+
+抽象类介于接口和类之间,
+
### 泛型类
-### 特殊类函数
+### 特殊类
-#### component 函数
+#### object
+
+#### data class
+
+#### enum class
+
+### 特殊类函数
#### 重写 toString
#### 重载运算符
-## 委托
+#### component 函数
+
+#### invoke
+
+类似于 Python 的 `__call__()`
## 特殊函数
-### 嵌套 lambda 与注解
+### 嵌套 lambda 与标签
### 泛型函数
@@ -103,21 +213,32 @@ class MyClass(
#### 概念与 lambda 变量类型
-#### 常用的扩展函数
+#### 常用的标准库扩展函数
##### apply
+它的返回值是对象本身,lambda 相当于类函数。
+
```kotlin
+val user = User().apply {
+ name = "Alice"
+ age = 18
+} // 修改对象属性后返回 user 对象本身
```
##### also
+它的返回值是对象本身,lambda 相当于参数是同类的函数。
+
```kotlin
+val numbers = mutableListOf(1, 2, 3).also {
+ println("The list elements were: $it")
+} // numbers 仍是是可变 List
```
##### let
-`let` 可以让一段代码只在对象非空时执行:
+可以利用 `let` 让一段代码只在对象非空时执行:
```kotlin
val name: String? = "Kotlin"
@@ -129,40 +250,169 @@ name?.let {
如果 `name` 是 `null`,`let` 里面的代码不会执行。
-##### use
-
-
##### run
+它的返回值是最后的任意结果,lambda 相当于类函数。
+
```kotlin
+val result = StringBuilder().run {
+ append("Hello, ")
+ append("World!")
+ toString() // 返回结果
+}
+```
+
+##### use
+
+它的返回值是对象本身,lambda 相当于参数是同类的函数。
+但是仅用于继承了 AutoCloseable 的类,相当于 Java 的 try-with-resources。
+
+```kotlin
+val fileContent = File(filePath)
+ .bufferedReader()
+ .use { reader ->
+ reader.readText()
+ } // use 会自动调用 BufferedReader 的 close() 方法
```
### suspend 函数
+如果你的函数内部需要做一些不得不等待的事,或者需要很久的事的话,那么你可以选择给它添加 `suspend` 关键字。这样它可以在任意时间暂停。
+
+如果你想要调用一个 suspend 函数,那么你需要注意,它不能直接写在任何非 suspend 函数中。
+
+如果你非要在一个普通函数中使用 suspend 函数,那么你可以使用 `runBlocking`,它只有一个参数,一个 lambda,可以运行 suspend 函数并阻塞线程直到 lambda 运行完毕。
+
+更细致的讲解在 [成为 Kotlin 超人](./成为Kotlin超人.md) 的**协程**中。
+
## 文件 IO
-```kotlin
-```
-
-
-
-## 用 Gradle 加载依赖(外部库)
+Kotlin 的文件 IO 在 java.io.File 的基础上提供了许多充满 Kotlin 风味的方法。
```kotlin
+val file = File("example.txt") // 拿到文件(来自 Java)
+val content: String = file.readText() // 默认 UTF-8
+val lines: List = file.readLines()
+file.forEachLine { line ->
+ println(line)
+}
+
+file.writeText("Hello, Kotlin!") // 完全覆盖
+file.appendText("\nNew line data.") // 末尾添加
+
+File("my_folder").walk().forEach { file ->
+ println(file.absolutePath) // 遍历文件夹
+}
+
+val source = File("source.txt")
+val dest = File("dest.txt")
+source.copyTo(dest, overwrite = true) // 复制文件
```
+## 用 Gradle 加载依赖(外部库)
+
+### build.gradle.kts
+
+这是最常被修改的 gradle 配置文件,里面不只有依赖的设置,还有一些 JVM / Kotlin 的设置。这里不做详细介绍。对于一个普通的 Kotlin 项目,控制依赖的部分写在这里:
+
+```kotlin
+dependencies {
+ implementation("org.jetbrains.kotlin:kotlin-reflect")
+ // 加载最新版的 Kotlin 反射,但不是所有的库都能自动添加版本号
+ implementation("org.jetbrains.kotlinx:kotlinx-datetime:0.6.0")
+ // 加载0.6.0版本的 Kotlin 时间
+}
+```
+
+依赖的名称一般从 Maven 仓库中查找,不少在 GitHub 有仓库的 Kotlin 库会写明自己在 Maven 上的名称。
+
+有时会用到 `testImplementation`,它只在测试源文件中起作用。
+
+### settings.gradle.kts
+
+这个文件用的很少,我的建议是,一般别动。
+
+## 时间
+
+在 Kotlin 中可以直接使用 Java 的时间处理方法,如果需要实现复杂一点的逻辑或是需要用到 Kotlin 序列化(在[成为 Kotlin 超人](./成为Kotlin超人.md)中有讲解),更推荐使用 `kotlinx-datetime`。
+
+官方文档:[kotlinx-datetime](https://kotlinlang.org/api/kotlinx-datetime/kotlinx-datetime/)
+
+### 加载依赖
+
+可以在官方文档中找到目前的版本,随后在 build.gradle.kts 中写:
+
+```kotlin
+dependencies {
+ implementation("org.jetbrains.kotlinx:kotlinx-datetime:0.8.0")
+}
+```
+
+### 拿到当前时间或任意时间
+
+```kotlin
+val nowInstant = Clock.System.now()
+// 获取当前时刻 (UTC)
+
+val customDate = LocalDate(2026, 10, 1)
+// 也可以写成 LocalDate(2026, Month.OCTOBER, 1)
+
+val customTime = LocalTime(14, 30, 0) // 时, 分, 秒, 纳秒
+
+val customDateTime = LocalDateTime(2026, 10, 1, 14, 30, 0)
+
+println(customDate) // 2026-10-01
+println(customDateTime) // 2026-10-01T14:30:00
+
+println(nowInstant)
+// 2026-09-19T08:39:08.123Z
+println(nowInstant.toEpochMilliseconds())
+// 毫秒时间戳
+```
+
+### 分析日期
+
+```kotlin
+val localDateTime = currentMoment.toLocalDateTime(TimeZone.currentSystemDefault())
+
+println(localDateTime) // 2026-09-19T17:39:08.123
+println(localDateTime.year) // 年: 2026
+println(localDateTime.monthNumber) // 月: 9
+println(localDateTime.dayOfMonth) // 日: 19
+println(localDateTime.hour) // 时: 17
+println(localDateTime.minute) // 分: 39
+println(localDateTime.today) // 2026-09-19
+println(localDateTime.dayOfWeek) // SATURDAY 这是一个枚举类 DayOfWeek
+```
## Kotlin 反射
+### 拿到类变量
+
+### 利用类变量修改对象
+
```kotlin
```
## 定义一个特殊的变量/函数名
+只需要使用反引号 ``` ` ``` 将一个任意符串包裹起来,它几乎可以被定义为所有东西的名称。
```kotlin
+fun `fun`() = "fun" // 例如定义一个函数
+val `this` = 1 // 或是一个变量
```
+## IDEA 的常用快捷键
+
+`ctrl + alt + L`:格式化代码
+
+`ctrl + alt + O`:整理文件中的 import
+
+`alt + enter`:光标在警告 / 报错上时显示快速处理方案或光标处的格式转换
+
+`shift + F6`:重命名文件名 / 属性名
+
## 接下来可以看
[目录](../README.md)
@@ -171,4 +421,6 @@ name?.let {
[更进一步:成为 Kotlin 超人](./成为Kotlin超人.md)
-[进入 KMP](./进入KMP.md)
\ No newline at end of file
+[进入 KMP](./进入KMP.md)
+
+[KMP:复杂逻辑与多平台不同逻辑](./复杂逻辑与多平台不同逻辑.md)
\ No newline at end of file