[TOC]
## internal
在 Kotlin 中,`internal` 關鍵字用于指定類、對象、接口、構造函數、屬性、函數等的可見性范圍。被標記為 `internal` 的成員只能在同一個模塊中訪問。模塊的概念可以是一個 IntelliJ IDEA 模塊、一個 Maven 項目、一個 Gradle 源集等。
### `internal` 關鍵字的作用和使用場景
1. **限制可見性范圍**: `internal` 關鍵字限制了成員的可見性范圍,使其只能在同一個模塊內訪問。這對于控制代碼的訪問范圍、提高封裝性和避免意外的使用非常有用。
2. **模塊級別的訪問控制**: 它允許開發者在模塊內共享實現細節,但隱藏這些實現細節不被外部模塊看到。例如,某些類或函數在模塊內是必要的,但不希望它們被其他模塊依賴和使用時,可以使用 `internal`。
3. **提高代碼的可維護性**: 通過限制訪問范圍,可以減少模塊間的耦合,提高代碼的可維護性和重構的靈活性。
## actual
在 Kotlin 中,`actual` 關鍵字用于多平臺項目中的期望(expect)/實際(actual)機制。這種機制允許你在不同的平臺(如 JVM、JS、Native 等)中編寫特定于平臺的實現,同時共享公共代碼。
### 期望和實際的工作機制
1. **期望聲明** (`expect`):在共享模塊中聲明一個期望的類、函數或屬性,而不提供具體實現。
2. **實際實現** (`actual`):在具體平臺的模塊中提供對應的實現。
### 示例:
1. 定義期望聲明
```kotlin
// commonMain/src/commonMain/kotlin/com/example/Platform.kt
package com.example
expect class Platform() {
val name: String
}
```
2. 提供實際實現
JVM平臺實現:
```kotlin
// jvmMain/src/jvmMain/kotlin/com/example/Platform.kt
package com.example
actual class Platform {
actual val name: String = "JVM"
}
```
JS 平臺實現:
```kotlin
// jsMain/src/jsMain/kotlin/com/example/Platform.kt
package com.example
actual class Platform {
actual val name: String = "JS"
}
```
## typealias
在 Kotlin 中,`typealias` 關鍵字用于為現有類型定義一個新的別名。這可以使代碼更具可讀性,尤其是在處理長或復雜類型時。通過使用類型別名,可以簡化類型引用,使代碼更清晰、更易于維護。
```kotlin
typealias MyMapType = Map<String, List<Pair<Int, String>>>
val map: MyMapType = ...
```
## reified
在 Kotlin 中,`reified` 關鍵字用于內聯函數(`inline` functions),使得在運行時能夠訪問泛型參數的具體類型。這是一個非常有用的特性,因為通常在 JVM 上,泛型類型信息在編譯時會被擦除(type erasure),而 `reified` 關鍵字能夠保留和使用這些類型信息。
```kotlin
fun <T> parseJson(json: String, clazz: Class<T>): T {
// 使用傳入的 Class 對象進行解析
return Gson().fromJson(json, clazz)
}
// 使用時
val user = parseJson(jsonString, User::class.java)
```
## inline
在 Kotlin 中,`inline` 關鍵字用于內聯函數。內聯函數的主要作用是避免因函數調用而產生的開銷,通過在編譯時將函數的字節碼直接插入到調用處,來減少運行時的開銷。這對于某些場景下的性能優化非常有用,尤其是在高頻率調用的函數中。
### 使用場景
* **高頻調用的小函數**:如高階函數、lambda 表達式等。
* **需要保留泛型類型信息的函數**:與 `reified` 泛型參數配合使用。
* **消除閉包開銷**:當 lambda 表達式捕獲了上下文中的變量時,會產生閉包對象。內聯函數可以減少這些閉包的創建。
## noinline
在 Kotlin 中,`noinline` 關鍵字用于修飾內聯函數的參數,使其在內聯函數體內不被內聯。通常與 `inline` 關鍵字配合使用。默認情況下,內聯函數的所有 lambda 參數都會被內聯,而有時我們希望某些 lambda 參數不要被內聯,此時就可以使用 `noinline` 關鍵字。
### 使用場景
* **部分參數不內聯**:在某些情況下,出于性能或代碼結構的考慮,你可能希望內聯函數的某些 lambda 參數不被內聯。
* **延遲執行的 lambda**:當 lambda 參數需要在內聯函數之外的上下文中被使用或傳遞時,需要使用 `noinline`。
```kotlin
inline fun process(
inlineLambda: () -> Unit,
noinline deferredLambda: () -> Unit
) {
inlineLambda()
executeLater(deferredLambda)
}
fun executeLater(action: () -> Unit) {
// Simulate some delay
Thread.sleep(1000)
action()
}
fun main() {
process(
inlineLambda = { println("Executing inline lambda immediately") },
deferredLambda = { println("Executing noinline lambda later") }
)
}
```
## crossinline
在Kotlin中,`crossinline`關鍵字用于修飾高階函數的參數,以確保這些參數在內聯(inline)時不會被非局部返回(non-local returns)打斷。
使用`crossinline`修飾的參數不允許非局部返回。這對于確保傳遞的lambda表達式不能意外地中斷包含它的內聯函數非常重要。這在某些情況下是必要的,特別是在高階函數的實現中,例如在異步執行或多線程環境中。
示例代碼:
```kotlin
inline fun inlineFunction(block: () -> Unit) {
// 調用傳遞的lambda
block()
}
fun callerFunction() {
inlineFunction {
// 非局部返回
return
}
println("This will not be printed")
}
```
在上述代碼中,`inlineFunction`是一個內聯函數,接受一個`block`參數。`block`參數可以進行非局部返回,從而使得`callerFunction`函數在lambda中執行返回操作后直接退出。
```kotlin
inline fun inlineFunction(crossinline block: () -> Unit) {
// 調用傳遞的lambda
block()
}
fun callerFunction() {
inlineFunction {
// 非局部返回將導致編譯錯誤
// return // This line will cause a compile-time error
println("Inside lambda")
}
println("This will be printed")
}
```
在這個例子中,通過在參數前添加`crossinline`關鍵字,`block`參數不允許非局部返回。如果嘗試在lambda表達式中執行`return`操作,將會導致編譯錯誤。
## infix
在 Kotlin 中,`infix` 關鍵字用于定義中綴函數(infix functions)。中綴函數是一種特殊的成員函數或擴展函數,它們可以以中綴表示法(即不使用點和括號)調用,從而提高代碼的可讀性和簡潔性。使用 `infix` 關鍵字定義的函數必須滿足以下條件:
1. 它是成員函數或擴展函數。
2. 它只有一個參數。
3. 它用 `infix` 關鍵字修飾。
```kotlin
infix fun Int.times(str: String): String {
return str.repeat(this)
}
fun main() {
val result = 3 times "Hello "
println(result) // 輸出: Hello Hello Hello
}
```
## sealed
在 Kotlin 中,`sealed` 關鍵字用于聲明密封類(sealed class)。密封類是一種特殊的類,可以有多個子類,但這些子類必須聲明在同一個文件中。密封類的主要目的是限制繼承的可能性,從而更好地控制類層次結構,并在使用 `when` 表達式時提供更強的類型安全性。
### 特性和用法
1. **密封類聲明**: 使用 `sealed` 關鍵字來聲明一個密封類。
2. **限制繼承**: 密封類的所有直接子類必須聲明在同一個文件中,但它們可以聲明為嵌套類或者在文件的其他位置聲明。
3. **提高 `when` 表達式的安全性**: 使用 `when` 表達式處理密封類時,如果分支覆蓋了所有可能的子類,編譯器將不會要求添加 `else` 分支。
```kotlin
sealed class Result
data class Success(val data: String) : Result()
data class Failure(val error: String) : Result()
object Loading : Result()
```
- 寫在前面的話
- Java
- 基礎
- Double的比較
- 小數怎么用二進制表示
- 多線程
- 并發和并行
- 線程池
- 線程池背景
- 線程池構造
- 任務阻塞隊列
- Flutter
- 基礎知識
- Dart基礎
- Android
- 項目架構
- View
- 非UI線程更新View
- AlarmManager
- 對比postDelaryed和Timer
- Bitmap
- 加載100M的圖片卻不撐爆內存
- Bitmap壓縮
- Bitmap局部解碼
- 計算圖片的內存占用
- Android動畫
- Android動畫類型
- Android動畫原理
- 屬性動畫
- 幀動畫
- 補間動畫
- 使用動畫的注意事項
- Android新特性
- 權限組
- Android23(Marshmallow)-6.0
- Android24(Nougat)-7.0
- Android26(Oreo)-8.0
- Android28(Pie)-9.0
- Android29(Q)-10.0
- AndroidX遷移
- Kotlin
- 關鍵字
- Kotlin操作符
- CoroutineScope
- Flow
- CoroutineException