Kotlin 高階語法解析

Kotlin 高級語法深度解析

  • 1. 協程(Coroutines)
    • 1.1 基礎概念
      • 1.掛起和恢復
      • 2.協程構建器 (Coroutine Builders)
      • 3.協程作用域
      • 4.調度器
    • 1.2 核心用法
    • 1.3 實戰示例
  • 2. 密封類(Sealed Classes)
    • 2.1 定義與特性
    • 2.2 模式匹配
    • 2.3 應用場景
  • 3. 內聯函數(Inline Functions)
    • 3.1 基礎用法
    • 3.2 關鍵字擴展
  • 4. 擴展函數(Extension Functions)
    • 4.1 基礎定義
    • 4.2 最佳實踐
  • 5. 類型系統進階
    • 5.1 空安全
    • 5.2 泛型系統
  • 6. 作用域函數(Scope Functions)
  • 7. 數據類與解構
    • 7.1 數據類特性
    • 7.2 解構擴展
  • 8. 委托 (Delegation)
    • 8.1 類委托
    • 8.2 屬性委托
  • 9.高階函數 和 Lambda 表達式
  • 10. 高級特性應用
    • 10.1 DSL構建
    • 10.2 反射與元編程
  • 11.Flow 數據流處理
    • 11.1創建 Flow
    • 11.2 Flow 的生命周期操作符
    • 11.3流上下文 (Context) 與 flowOn

1. 協程(Coroutines)

協程是 Kotlin 處理異步編程和并發的利器,它允許你以同步的代碼風格編寫異步邏輯,避免了回調地獄

1.1 基礎概念

1.掛起和恢復

暫停當前協程的執行,并釋放它占用的線程資源,讓線程去執行其他任務。當掛起的操作(如網絡請求返回)完成后,協程會在合適的線程上恢復執行。

// 聲明一個掛起函數
suspend fun fetchUserData(): User {// ... 執行耗時操作,如網絡請求return withContext(Dispatchers.IO) { // 切換到 IO 線程池執行// 模擬網絡請求delay(1000) // 這是一個掛起函數,非阻塞地延遲User("John") // 返回結果}
}
// 掛起函數只能在另一個掛起函數或協程中被調用

2.協程構建器 (Coroutine Builders)

用于啟動一個新的協程。

  • launch: 啟動一個新協程,不返回結果。用于執行一段“一勞永逸”的工作(Fire-and-forget)。

fun main() = runBlocking {val job = launch { // 返回一個 Job 對象,用于管理協程delay(1000L)println("World!")}println("Hello,")job.join() // 等待協程執行完畢
}
// 輸出: Hello, (等待1秒) World!
  • async: 啟動一個新協程,并返回一個 Deferred 對象(一個輕量級的、帶有結果的
    Future)。用于并行執行任務并獲取結果,通常與 await() 一起使用。
suspend fun concurrentSum(): Int = coroutineScope {val deferred1 = async { fetchData1() } // 立即啟動異步任務1val deferred2 = async { fetchData2() } // 立即啟動異步任務2deferred1.await() + deferred2.await() // 等待兩個任務都完成并求和
}

3.協程作用域

通過coroutineScope、viewModelScope等管理生命周期

GlobalScope: 全局作用域,生命周期與應用程序一樣長。應謹慎使用,容易造成協程泄漏。

coroutineScope: 一個掛起函數,用于創建一個新的作用域,它會等待所有子協程完成后才完成自身。如果子協程失敗,它會取消所有其他子協程并傳播異常。

supervisorScope: 類似 coroutineScope,但子協程的失敗不會導致其他子協程取消( supervision )。適用于獨立的并行任務。

Android 中的生命周期感知作用域:

viewModelScope (在 ViewModel 中使用)

lifecycleScope (在 Activity/Fragment 中使用)

4.調度器

決定協程在哪個或哪些線程上執行

Dispatchers.Main: 在主線程(UI線程)上執行。用于更新 UI 和進行輕量級操作。

Dispatchers.IO: 專為磁盤和網絡 I/O 操作優化。使用共享的線程池。

Dispatchers.Default: 專為 CPU 密集型計算任務優化。使用共享的線程池,其大小與 CPU 核心數相同。

Dispatchers.Unconfined: 不限制任何特定線程。不推薦新手使用。

1.2 核心用法

// 結構化并發示例
viewModelScope.launch {try {val user = async { fetchUser() }val news = async { fetchNews() }updateUI(user.await(), news.await())} catch (e: Exception) {showError(e)}
}// 線程切換
suspend fun loadData() = withContext(Dispatchers.IO) {// 網絡請求
}

1.3 實戰示例

Android 中的典型用法

// 在 ViewModel 中
class MyViewModel : ViewModel() {// 使用 viewModelScope,當 ViewModel 被清除時自動取消所有協程fun loadUserData() {viewModelScope.launch { // 在主線程啟動_uiState.value = UiState.Loadingtry {// 切換到 IO 線程執行網絡請求和數據庫操作val userProfile = withContext(Dispatchers.IO) {// 并行執行兩個異步任務val userDeferred = async { api.getUser() }val postsDeferred = async { api.getPosts() }UserProfile(userDeferred.await(), postsDeferred.await())}// 回到主線程更新狀態_uiState.value = UiState.Success(userProfile)} catch (e: Exception) {// 回到主線程處理錯誤_uiState.value = UiState.Error(e.message)}}}
}

2. 密封類(Sealed Classes)

密封類用于表示受限的類繼承結構,當一個值只能是有限幾種類型之一時非常有用,常與 when 表達式結合使用,確保窮舉檢查。

2.1 定義與特性

sealed class Result<out T> {data class Success<T>(val data: T) : Result<T>()data class Error(val exception: Exception) : Result<Nothing>()object Loading : Result<Nothing>()
}

2.2 模式匹配

fun handleResult(result: Result<String>) {when (result) {is Result.Success -> println("Data: ${result.data}")is Result.Error -> println("Error: ${result.exception}")Result.Loading -> println("Loading...")}
}

2.3 應用場景

UI狀態管理(Idle/Processing/Success/Failure)
API響應處理(Success/Error/NetworkError)

3. 內聯函數(Inline Functions)

使用 inline 關鍵字修飾的函數,在編譯時會將其函數體直接插入到調用處,可以減少函數調用的開銷,尤其適用于接收 Lambda 作為參數的高階函數,可以避免 Lambda 對象的創建。

3.1 基礎用法

// 高階函數內聯優化
inline fun <T> measureTime(block: () -> T): T {val start = System.nanoTime()return block().also { println("Time: ${System.nanoTime() - start}") }
}// 使用示例
val result = measureTime {// 耗時操作
}

3.2 關鍵字擴展

noinline:禁止內聯特定lambda參數
crossinline:禁止lambda內部使用return
reified:具體化泛型類型參數

inline fun <reified T> Activity.openAct() {startActivity(Intent(this, T::class.java))
}

4. 擴展函數(Extension Functions)

4.1 基礎定義

// 為String添加反轉方法
fun String.reverse(): String {return this.reversed()
}// Android擴展
fun Context.showToast(message: String) {Toast.makeText(this, message, Toast.LENGTH_SHORT).show()
}

4.2 最佳實踐

組織方式:按功能模塊分組擴展函數
作用域:優先擴展接口而非具體類
性能優化:避免過度擴展基礎類型

5. 類型系統進階

5.1 空安全

// 安全調用鏈
val length: Int? = text?.length
val safeLength = text?.length ?: 0// 非空斷言
val forcedLength = text!!.length

5.2 泛型系統

協變(out T):生產者角色
逆變(in T):消費者角色
類型投影:Array
Kotlin 使用聲明處型變,解決了 Java 通配符 (? extends T, ? super T) 的復雜性問題。

1.out (協變 Covariant):生產者,只能輸出(返回)T。Producer<out T> 是 Producer<U> 的子類型,如果 T 是 U 的子類型。類似于 Java 的 ? extends T。interface Producer<out T> {fun produce(): T // T 只出現在 out 位置
}
2.in (逆變 Contravariant):消費者,只能輸入(消耗)T。Consumer<in T> 是 Consumer<U> 的子類型,如果 T 是 U 的父類型。類似于 Java 的 ? super T。interface Consumer<in T> {fun consume(item: T) // T 只出現在 in 位置
}

6. 作用域函數(Scope Functions)

Kotlin 提供了幾個作用域函數:let, run, with, apply, also。它們的主要目的是在對象的上下文中執行代碼塊,并且各自有細微的差別(返回值和 this/it 的指代)。

函數對象引用返回值適用場景
letitlambda結果對象為空時跳過操作
runthislambda結果需要計算多個屬性時
withthislambda結果配置對象參數
applythis對象自身對象初始化配置
alsoit對象自身對象副作用操作

示例:


// 對象初始化
val user = User().apply {name = "John"age = 30
}// 條件判斷
val result = data?.let { process(it) } ?: defaultValue

7. 數據類與解構

允許將一個對象的多個屬性或組件一次性賦值給多個變量。

7.1 數據類特性

data class User(val name: String, val age: Int)
自動生成equals()/hashCode()/toString()
支持copy()方法
解構聲明:val (name, age) = user

7.2 解構擴展

原理: 編譯器會調用對象的 component1(), component2() 等運算符函數。數據類(data class)會自動生成這些函數。

// 為現有類添加解構支持
data class Person(val name: String, val age: Int)fun main() {val person = Person("Alice", 29)// 解構聲明:根據主構造函數中聲明的屬性順序val (name, age) = personprintln("$name is $age years old") // 輸出: Alice is 29 years old// 對于集合也適用(因為 componentN() 函數)val (first, second, third) = listOf("a", "b", "c")println("$first, $second, $third") // 輸出: a, b, c
}

8. 委托 (Delegation)

Kotlin 原生支持委托模式,通過 by 關鍵字實現,可以將一個類的接口實現委托給另一個對象。

8.1 類委托

interface Base {fun print()
}class BaseImpl(val x: Int) : Base {override fun print() { print(x) }
}// Derived 類將 Base 接口的實現委托給 baseObject
class Derived(b: Base) : Base by bfun main() {val b = BaseImpl(10)Derived(b).print() // 輸出: 10
}

8.2 屬性委托

最常用的是 lazy 和 observable

import kotlin.properties.Delegatesclass Example {// 延遲初始化,第一次訪問時才計算val lazyValue: String by lazy {println("computed!")"Hello"}// 可觀察屬性,值改變時會觸發回調var observedValue: String by Delegates.observable("<no name>") {prop, old, new ->println("$old -> $new")}
}fun main() {val e = Example()println(e.lazyValue) // 第一次訪問,輸出: computed! 然后輸出: Helloprintln(e.lazyValue) // 第二次訪問,直接輸出: Helloe.observedValue = "first" // 輸出: <no name> -> firste.observedValue = "second" // 輸出: first -> second
}

9.高階函數 和 Lambda 表達式

高階函數是將函數用作參數或返回值的函數。Lambda 表達式是定義匿名函數的簡潔方式。

// 定義一個高階函數
fun calculate(x: Int, y: Int, operation: (Int, Int) -> Int): Int {return operation(x, y)
}fun main() {// 使用 Lambda 表達式val addResult = calculate(10, 5) { a, b -> a + b }println(addResult) // 輸出: 15// 使用函數引用 (::)val multiplyResult = calculate(10, 5, ::multiplyHelper)println(multiplyResult) // 輸出: 50// 另一個例子:使用集合的高階函數val numbers = listOf(1, 2, 3, 4, 5)val evenSquares = numbers.filter { it % 2 == 0 }   // 過濾偶數.map { it * it }          // 計算平方println(evenSquares) // 輸出: [4, 16]
}fun multiplyHelper(a: Int, b: Int) = a * b

要點:

it:如果 Lambda 只有一個參數,可以使用默認名稱 it。

最后一個 Lambda:如果函數的最后一個參數是 Lambda,它可以移到括號外面。如果它是唯一參數,括號可以省略。這是 Kotlin DSL 的基礎。

()->Unit:表示一個無參數無返回值的函數類型。

10. 高級特性應用

10.1 DSL構建

// RecyclerView DSL示例
recyclerView.build {layoutManager = LinearLayoutManager(context)adapter {itemType<User> {layoutRes = R.layout.item_userbind { holder, user ->holder.name.text = user.name}}}
}

10.2 反射與元編程

完整支持Java反射API
Kotlin反射庫:kotlin-reflect 在運行時動態地檢查、訪問和操作類、對象、屬性、函數等。功能強大,但性能開銷較大。

import kotlin.reflect.full.*data class Person(val name: String, var age: Int)fun main() {val person = Person("Alice", 29)val kClass = person::class // 獲取 KClass 對象// 檢查成員kClass.memberProperties.forEach { println(it.name) } // 輸出: name, age// 訪問屬性值val ageProperty = kClass.declaredMemberProperties.find { it.name == "age" }println(ageProperty?.get(person)) // 輸出: 29// 調用函數val kFunction = ::Person // 獲取構造函數引用val newPerson = kFunction.call("Bob", 30)println(newPerson) // 輸出: Person(name=Bob, age=30)
}

11.Flow 數據流處理

Flow 是 Kotlin 協程庫中用于處理異步數據流(Asynchronous Streams)的組件。它可以按順序發射多個值,而不是像 suspend 函數那樣只返回單個值。你可以把它想象成一個“異步序列”或“響應式流”,類似于 RxJava 的 Observable 或 Reactor 的 Flux。

11.1創建 Flow

最常用的創建方式是使用 flow { … } 構建器。

import kotlinx.coroutines.*
import kotlinx.coroutines.flow.*// 創建一個簡單的 Flow,發射 1 到 3 三個數字
fun simpleFlow(): Flow<Int> = flow {println("Flow started")for (i in 1..3) {delay(1000) // 模擬一個異步操作,比如網絡請求emit(i) // 發射一個值到流中}
}suspend fun main() = runBlocking {// 第一次收集:會觸發 Flow 的執行println("Calling collect first time...")simpleFlow().collect { value -> println("Collected $value") }// 等待一段時間后再次收集delay(3000)// 第二次收集:會再次觸發一個全新的、獨立的執行println("Calling collect second time...")simpleFlow().collect { value -> println("Collected again $value") }
}

輸出:

Calling collect first time…
Flow started Collected 1 // 等待1秒后
Collected 2 // 再等待1秒后
Collected 3 // 再等待1秒后
Calling collect second
time… Flow started // 再次打印,證明是新的執行
Collected again 1
Collected again 2
Collected again 3

11.2 Flow 的生命周期操作符

Flow 提供了類似集合的操作符,但它們是中間操作符,返回一個新的 Flow,并且大多是冷的。

轉換操作符 (Transform Operators)

  • map: 將每個發射的值進行轉換。

  • filter: 過濾發射的值。

  • transform: 更通用的轉換,可以發射任意次數的值。

suspend fun main() = runBlocking {(1..5).asFlow() // 將集合轉換為 Flow.filter { it % 2 == 0 } // 過濾偶數.map { it * it } // 將偶數平方.collect { println(it) } // 收集結果:4, 16
}- 限長操作符 (Size-limiting Operators)
take: 只取前 N 個值,然后取消流的執行。
suspend fun main() = runBlocking {flow {try {emit(1)emit(2)println("This will not print")emit(3) // 因為 take(2),執行到這里之前流已被取消} finally {println("Finally in flow") // 仍然會執行,用于資源清理}}.take(2).collect { println(it) } // 輸出: 1, 2, Finally in flow
}
  • 末端操作符 (Terminal Operators)
    末端操作符是掛起函數,它啟動流的收集。最常見的末端操作符是 collect。
  • collect: 收集所有發射的值。
  • toList / toSet: 將流收集到集合中。
  • first() / single(): 獲取第一個或唯一一個值。
  • reduce / fold: 對流進行聚合操作。
suspend fun main() = runBlocking {val sum = (1..5).asFlow().reduce { accumulator, value -> accumulator + value } // 累加: 1+2+3+4+5println(sum) // 輸出: 15
}

11.3流上下文 (Context) 與 flowOn

Flow 的構建器代碼默認在收集器所在的協程上下文中運行。如果要改變流發射的上下文(例如,切換到 IO 線程進行網絡請求),需要使用 flowOn 操作符。

fun simpleFlow(): Flow<Int> = flow {println("Started in ${Thread.currentThread().name}") // 在 IO 線程執行for (i in 1..3) {delay(100)emit(i)}
}.flowOn(Dispatchers.IO) // 指定上游流的執行上下文suspend fun main() = runBlocking {println("Collecting in ${Thread.currentThread().name}") // 在主線程收集simpleFlow().collect { value ->println("$value collected in ${Thread.currentThread().name}") // 在主線程收集}
}

輸出:

text Collecting in main @coroutine#1
Started in DefaultDispatcher-worker-1 @coroutine#2
1 collected in main @coroutine#1
2 collected in main @coroutine#1
3 collected in main @coroutine#1

注意:flowOn 改變了它之前的操作符的上下文。收集操作 collect 仍然在原始的上下文中。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/pingmian/97890.shtml
繁體地址,請注明出處:http://hk.pswp.cn/pingmian/97890.shtml
英文地址,請注明出處:http://en.pswp.cn/pingmian/97890.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

9 基于機器學習進行遙感影像參數反演-以隨機森林為例

目錄 1 讀取數據 2 數據預處理 3模型訓練 4模型預測 5精度分析 由于回歸任務的標簽數據獲取比較困難,我們這次用水體指數NDWI來模擬作為回歸任務的標簽,通過隨機森林來擬合回歸NDWI,其計算公式如下: NDWI = (band3 - band5) / (band3 + band5) 實際情況下需要回歸的數…

C++多線程編程:跨線程操作全解析

C中的"線程"通常指單個執行流&#xff08;如std::thread對象&#xff09;&#xff0c;而"多線程"指程序中同時存在多個這樣的執行流&#xff0c;并涉及它們的創建、管理和同步。實現跨線程操作的核心在于安全地處理共享數據和線程間通信。 以下是實現跨線程…

【腦電分析系列】第13篇:腦電源定位:從頭皮到大腦深處,EEG源定位的原理、算法與可視化

前言腦電信號&#xff08;Electroencephalography, EEG&#xff09;是一種非侵入性的神經成像技術&#xff0c;能夠實時捕捉大腦的電活動。然而&#xff0c;頭皮上記錄到的信號是腦源活動經過頭皮、顱骨等介質“模糊”后的投影。想要從這些頭皮EEG信號追溯到大腦深處的電活動&a…

MySQL知識筆記

DATE_ADD(date,INTERVAL expr type) date 參數是合法的日期表達式。expr 參數是您希望添加的時間間隔。多查官方手冊&#xff01;&#xff01;命令行啟動和停止sql服務net start 數據庫名&#xff1b; 這是啟動服務命令&#xff1b; 例如&#xff1a;net start Mysql56…

2025算法八股——深度學習——MHA MQA GQA

MHA、MQA、GQA 都是深度學習中注意力機制的相關概念&#xff0c;其中 MHA 是標準的多頭注意力機制&#xff0c;MQA 和 GQA 則是其優化變體&#xff0c;以下是它們的區別、優缺點介紹&#xff1a;區別MHA&#xff08;多頭注意力&#xff09;&#xff1a;是 Transformer 架構的核…

Vue3》》eslint Prettier husky

安裝必要的依賴 npm install -D eslint eslint/js vue/eslint-config-prettier prettier eslint-plugin-vue 初始化 ESLint 配置 npm init eslint/config// eslint.config.js // 針對 JavaScript 的 ESLint 配置和規則。保持 JavaScript 代碼的一致性和質量 import js from &qu…

Custom SRP - Point and Spot Lights

https://catlikecoding.com/unity/tutorials/custom-srp/point-and-spot-lights/Lights with Limited Influence1 Point Lights1.1 Other Light Data (Point )同方向光一樣,我們支持有限數量的 Other Light.盡管場景中可能有很多 Other Lights,可能有超過光源上限的光源時可見的…

hive數據倉庫的搭建

提示&#xff1a;文章寫完后&#xff0c;目錄可以自動生成&#xff0c;如何生成可參考右邊的幫助文檔 文章目錄前言一、內嵌模式二、本地模式三、遠程模式前言 HIVE是基于HDFS的數據倉庫&#xff0c;要首先搭建好HADOOP的集群才可以正常使用HIVE&#xff0c;HADOOP集運搭建詳見…

域名SSL證書免費申請lcjmSSL

.-.lcjmSSL&#xff08;又名“來此加密”&#xff09;是一個提供免費SSL證書申請的一站式平臺。它支持單域名、多域名以及泛域名證書申請&#xff0c;且單張證書最高可覆蓋100個域名&#xff0c;讓您輕松實現全站HTTPS加密。為什么您的網站必須安裝SSL證書&#xff1f;數據加密…

“能量逆流泵”:一種基于電容陣與開關矩陣的超高效大功率降壓架構

摘要本文提出并驗證了一種面向大功率降壓應用的革命性電源架構——"能量逆流泵"&#xff08;Energy Inversion Pump, EIP&#xff09;。該架構摒棄了傳統Buck轉換器中的電感元件&#xff0c;通過高速開關矩陣控制的電容陣列&#xff0c;將高壓側能量以"分時、分…

打造精簡高效的 uni-app 網絡請求工具

在 uni-app 開發中&#xff0c;網絡請求是連接前端與后端的核心橋梁。一個設計良好的請求工具能夠顯著提升開發效率&#xff0c;減少重復代碼。本文將分享一個精簡版的 uni-app 網絡請求工具實現&#xff0c;它保留了核心功能同時保持了足夠的靈活性。設計思路一個優秀的網絡請…

【面試場景題】交易流水表高qps寫入會有鎖等待或死鎖問題嗎

文章目錄一、先明確交易流水表的核心特性二、InnoDB的鎖機制在流水表寫入場景的表現1. 行鎖&#xff08;Record Lock&#xff09;&#xff1a;基本不涉及2. 間隙鎖&#xff08;Gap Lock&#xff09;與Next-Key Lock&#xff1a;幾乎不觸發3. 表鎖&#xff1a;僅在極端場景出現三…

項目部署——LAMP、LNMP和LTMJ

前情提要問&#xff1a;如何通過nginx的反向代理&#xff0c;代理多臺虛擬主機&#xff08;一臺apache服務器上的虛擬主機&#xff09;&#xff1f;1.在nginx的配置文件中&#xff0c;將基于域名的訪問改為基于端口的訪問&#xff08;nginx.conf&#xff09;upstream daili{ser…

晨曦中,它已勞作:一臺有溫度的機器人如何重塑我們的潔凈日常

清晨六點&#xff0c;城市的輪廓在微光中逐漸清晰。某高端小區的路面上&#xff0c;一臺灰色機身、線條流暢的機器正在安靜地工作。它繞過停靠的車輛&#xff0c;精準地沿著路緣石前進&#xff0c;吸走落葉與塵土&#xff0c;遇到突然竄出的流浪貓時輕巧避讓&#xff0c;仿佛有…

【最新高級版】酷柚易汛生產管理系統v1.2.8 +uniapp全開源+文檔教程

酷柚易汛生產管理系統是基于FastAdminThinkPHPLayuiuniapp開發的生產管理系統&#xff0c;幫助企業數字化轉型&#xff0c;打造智能工廠&#xff0c;專業為生產企業量身開發的一套完整的生產管理系統。主要包含以下模塊&#xff1a;購貨模塊、生產模塊、倉庫模塊、資料模塊&…

40分鐘的Docker實戰攻略

一&#xff1a;什么是Docker &#xff08;1&#xff09;基本概念 Docker 是一種開源的 容器化平臺&#xff0c;用于快速構建、部署和運行應用程序。它通過將應用程序及其依賴項打包到輕量級的、可移植的容器中&#xff0c;實現了環境一致性&#xff0c;解決了“在我機器上能運…

qt使用camke時,采用vcpkg工具鏈設置OSG的qt模塊osgQOpenGLWidget

【免費】osgQOpenGLWidget嵌入qt模塊,VS2022使用cmake的方式,工具鏈vcpkg資源-CSDN下載 CMake中設置 1.查找osg相關的庫,同時也會設置對應include的路徑 # 檢查是否找到 osg find_package(OpenSceneGraph 3.6.5REQUIRED COMPONENTS osgosgUtilosgGAosgViewerosgDBosgAnimatio…

洛谷 P2245 星際導航(kruskal 重構樹 + 倍增優化求路徑最大邊權)

題目鏈接 題目難度 洛谷上是藍題&#xff0c;我覺得這道題挺簡單的&#xff0c;一眼就看穿了&#xff0c;應該是綠題。 題目解法概括 kruskal 重構樹 倍增優化求路徑最大邊權。 代碼 #include <iostream> #include <vector> #include <algorithm> #in…

STM32H743-ARM例程1-IDE環境搭建與調試下載

目錄實驗平臺環境搭建一、Keil MDK集成開發環境1.MDK簡介2.MDK5安裝3.程序下載與調試二、STM32CubeMX1.STM32CubeMX簡介2.JAVA JRE安裝3.STM32CubeMX安裝4.STM32CubeH7庫安裝實驗平臺 硬件&#xff1a;銀杏科技GT7000雙核心開發板-ARM-STM32H743XIH6&#xff0c;銀杏科技iTool…

FPGA學習篇——Verilog學習MUX的實現

PS&#xff1a;目前手上仍然沒有板子&#xff0c;按照野火視頻的講解&#xff0c;目前我們只能做到前面六步&#xff08;其實第一步設計規劃也是需要看板子的硬件的&#xff0c;但是現在沒有板子就完全與野火傳授的板子一致來看&#xff09; 首先我們以最簡單的2路選擇器MUX2_1…