Kotlin的5個主要作用域函數

?applay, also,let, run, with 是kotlin標準庫提供的5個主要的作用域函數(Scope Functions)?,它們的設計目的是為了在特定作用域內更簡潔地操作對象。

如何使用這5個函數,要從它的設計目的來區分:

  1. apply : 配置/對象初始化, 返回對象本身
  2. also :?副作用操作/鏈式中間處理,返回對象本身
  3. let : 空安全轉換/數據映射,返回Lambda結果
  4. run : 對象計算/鏈式操作,返回Lambda結果
  5. with : 非擴展函數版的?run?,返回Lambda結果

深度解析每個函數

1.apply

public inline fun <T> T.apply(block: T.() -> Unit): T {block() // 配置對象return this // 返回自身
}

特點:

  • 隱式?this?引用
  • 專為對象初始化/配置設計
  • ?Lambda 是擴展函數?:可以直接訪問對象成員
val dialog = AlertDialog.Builder(context).apply {setTitle("提示")setCancelable(false)}

這是一個非常典型的建造者模式。其內部的setTitle方法可能是這樣的:

class Builder (private val context: Context) {private var title: String = ""fun setTitle(title: String) = apply {this.title = title}
}

上面的代碼你可能看著有些奇怪 = apply {}

上面的代碼等效于:

fun setTitle(title: String): Builder {this.title = titlereturn this
}

這里會引入一個概念單表達式函數(Single-Expression Functions)

fun add(a: Int, b: Int): Int {return a + b
}// 標準形式:用 = 替代 { return ... }
fun add(a: Int, b: Int): Int = a + b

在看上面 無論?block?里有多少行代碼,apply{}??本身是一個返回?this?的表達式?, 如果你還不理解

fun max(a: Int, b: Int){if (a > b)return aelse return b
}fun max(a: Int, b: Int): Int = if (a > b) a else b

它只是需要一個表達式,而apply{}恰好滿足這個表達式?

無論?block?里有多少行代碼,apply??本身是一個返回?this?的表達式?

val person = Person().apply {name = "John"      // this.name = "John"age = 30           // this.age = 30city = "New York"  // this.city = "New York"
}
這個是一個初始化的例子等價與
val person = Person()
person.name = "John"
person.age = 30
person.city = "New York"

2.also

public inline fun <T> T.also(block: (T) -> Unit): T {block(this) // 執行副作用return this // 返回自身
}

特點?:

  • 顯式?it?引用, 讓副作用操作更明確
  • 可空對象處理
  • 適合調試日志鏈式調用中的中間操作?
  • ?Lambda 是普通函數?:必須通過?it?引用對象
phone?.also {require(it)//副作用 
}?.process()

?驗證并繼續使用原對象。判空如果不做類型轉換建議使用also。

?

3.let

public inline fun <T, R> T.let(block: (T) -> R): R {return block(this) // 將 this 作為參數傳入 lambda
}

特點?:

  • 用?it?引用對象
  • 適合可空對象處理類型轉換?
val length = phone?.let { it.length } ?: 0

它的行為是把一個String類型轉換成了一個Int類型,類型轉換是它的重點。

4.run

public inline fun <T, R> T.run(block: T.() -> R): R {return block() // 以擴展函數方式調用
}

特點?:

  • 用?this?引用對象
  • 可與??.?結合處理可空對象
  • 適合同時訪問對象屬性和返回計算結果?
val description = user.run { "$name: ${calculateScore()}" }

5.with

public inline fun <T, R> with(receiver: T, block: T.() -> R): R {return receiver.block() // 非擴展函數版本
}

特點?:

  • 非擴展函數,需要顯式傳入接收者對象
  • 不能直接結合??.?處理可空對象?(需要額外判空)
  • 適合集中操作一個對象的場景
val result = with(config) {validate()buildResult()
}

我們可以看到這5個都是內聯函數(inline functions),其核心機制就是在編譯時進行代碼拷貝(或稱"代碼展開"),而不是在運行時進行函數調用。

為什么 Kotlin 標準庫函數用 inline?

  • ?避免 lambda 對象創建?:如果不內聯,每次調用都會生成一個匿名類實例
  • ?支持?return?控制流?:內聯后 lambda 中的?return?可以直接從外層函數返回

?

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

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

相關文章

原型模式Prototype Pattern

模式定義 用原型實例指定創建對象的種類&#xff0c;并且通過復制這些原型創建新的對象&#xff0c;其允許一個對象再創建 另外一個可定制的對象&#xff0c;無須知道任何創建的細節 對象創建型模式 基本工作原理是通過將一個原型對象傳給那個要發動創建的對象&#xff0c;這…

基于深度學習的智能交通流量預測系統:技術與實踐

前言 隨著城市化進程的加速&#xff0c;交通擁堵問題日益嚴重&#xff0c;給人們的日常生活和經濟發展帶來了巨大的挑戰。智能交通系統&#xff08;ITS&#xff09;作為解決交通問題的重要手段&#xff0c;逐漸成為研究的熱點。其中&#xff0c;交通流量預測是智能交通系統中的…

Cilium動手實驗室: 精通之旅---23.Advanced Gateway API Use Cases

Cilium動手實驗室: 精通之旅---23.Advanced Gateway API Use Cases 1. Lab說明1.1 高級網關 API 使用案例 2. 負載均衡器2.1 部署應用程序2.2 部署 Gateway 和 HTTPRoute 3. HTTP 標頭請求修飾符3.1 部署 HTTPRoute3.2 可觀測性 4. HTTP 響應標頭重寫5. HTTP 流量鏡像5.1 demo應…

Agentic Workflow是什么?Agentic Workflow會成為下一個AI風口嗎?

無論是想要學習人工智能當做主業營收&#xff0c;還是像我一樣作為開發工程師但依然要運用這個顛覆開發的時代寵兒&#xff0c;都有必要了解、學習一下人工智能。 近期發現了一個巨牛的人工智能學習網站&#xff0c;通俗易懂&#xff0c;風趣幽默&#xff0c;入行門檻低&#x…

Some chunks are larger than 500 KiB after minification. Consider

在 vue3vite 項目開發中&#xff0c;build 打包時出現以下警告報錯&#xff1a; (!) Some chunks are larger than 500 KiB after minification. Consider: - Using dynamic import() to code-split the application - Use build.rollupOptions.output.manualChunks to improve…

NodeJS11和10以及之前的版本,關鍵差異?

Node.js 11 相比 10&#xff08;及更早版本&#xff09;&#xff0c;除了事件循環行為的重大改變&#xff0c;還有多個核心模塊和底層機制的升級。以下是它們的關鍵差異和新特性對比&#xff0c;幫助你快速掌握兩個版本的重要變化。 &#x1f527; 一、事件循環行為變化&#x…

調和級數 斂散性

調和級數的斂散性是一個非常經典的問題。我們來全面分析它。 &#x1f9e0; 調和級數定義 調和級數是指&#xff1a; ∑ n 1 ∞ 1 n 1 1 2 1 3 1 4 ? \sum_{n1}^{\infty} \frac{1}{n} 1 \frac{1}{2} \frac{1}{3} \frac{1}{4} \cdots n1∑∞?n1?121?31?41?? …

Python?元組集合字符串

????˙?˙? ? 元組&#x1f6e5;?創建訪問修改解包其他操作比較的依據 集合&#x1f6f8;創建添加和刪除其他操作 字符串&#x1fa82;創建索引和切片基本操作連接加號join() 重復查找in 關鍵字index()find()startswith()endswith() ??替換??分割??大小寫刪除 能…

??信息系統項目管理師-項目整合管理 知識點總結與例題分析??

??一、項目整合管理概述?? ??1. 定義與重要性?? 項目整合管理是項目管理知識領域中的核心過程,它協調所有其他知識領域的過程和活動,確保項目各要素有效整合。其核心目標是: ??統一項目目標??:確保各要素服務于共同目標??協調沖突??:解決項目執行中的各…

『uniapp』onThemeChange監聽主題樣式,動態主題不正確生效,樣式被覆蓋的坑

目錄 問題示例代碼解決思路1&#xff08;缺點影響顯示效果有延遲&#xff09;解決思路2——通過路由刷新頁面&#xff08;缺點只適用于部分網頁&#xff09;解決思路3——vuex&#xff08;沒學會~&#xff09;總結 歡迎關注 『uniapp』 專欄&#xff0c;持續更新中 歡迎關注 『…

LeetCode 高頻 SQL 50 題(基礎版)【題解】合集

點擊下方標題可跳轉至對應部分&#xff1a; LeetCode 高頻 SQL 50 題&#xff08;基礎版&#xff09;之 【查詢】部分 LeetCode 高頻 SQL 50 題&#xff08;基礎版&#xff09;之 【連接】部分 上 LeetCode 高頻 SQL 50 題&#xff08;基礎版&#xff09;之 【連接】部分 下…

Jenkins 全面深入學習目錄

Jenkins 全面深入學習目錄 第一部分&#xff1a;Jenkins 基礎入門 Jenkins 概述 持續集成/持續交付(CI/CD)概念Jenkins 的歷史與發展Jenkins 與其他 CI/CD 工具的比較 Jenkins 安裝與配置 系統要求與環境準備不同操作系統下的安裝方法初始配置與安全設置插件管理系統 Jenkins…

安裝laravel11和laravel12的一些報錯問題解決

前言 今天在安裝laravel的過程中遇到一些報錯問題&#xff0c;記錄一下。 laravel 12 Root composer.json requires laravel/tinker ^2.10.1, found laravel/tinker[2.x-dev] but it does not match your minimum-stability laravel/framework[v12.0.0, ..., v12.15.0] requ…

Oracle21cR3之客戶端安裝錯誤及處理方法

文章目錄 Oracle21cR3客戶端安裝1. 下載2. 安裝解壓到指定位置&#xff0c;如下&#xff1a;2. 安裝 3. 常見錯誤1. 無法將 JINSHENGYUAN\jinshengyuan 安裝用戶添加到 %2% 組。1. 問題原因分析2. 處理方法 Oracle21cR3客戶端安裝 1. 下載 官網下載 2. 安裝 解壓到指定位置…

web3 資訊網址

1. 新聞 幣圈導航| 區塊鏈導航| WEB3導航 | 聚合幣圈交易所、行情工具、空投資訊、DeFi入口及行業動態&#xff0c;一站式區塊鏈資源門戶網站 2.github位置 https://github.com/itgoyo/awesome-crypto

【C++】簡單商品價格計算程序練習

相信你是最棒噠!!! 文章目錄 一、題目代碼 二、題目解析 1.解析版 2.簡潔版 總結 一、題目代碼 構建一個類book,其中含有兩個私有數據成員qu和price,將price初始化為qu的10倍,建立一個有5個元素的數組對象,將qu初始化為6~10。要求通過對象指針訪問對象數組,按相反的順序…

現代數據工程實踐:基于Dagster的ETL架構設計與實現

在當今數據驅動的世界中&#xff0c;有效的數據處理流程至關重要。本文將帶您通過一個完整的教程&#xff0c;學習如何使用Dagster構建一個功能強大的ETL(提取、轉換、加載)管道。無論您是數據工程師、分析師還是對數據流水線感興趣的技術愛好者&#xff0c;本教程都將為您提供…

golang-linux環境配置

下載源碼包 &#xff1a;All releases - The Go Programming Language 解壓文件 sudo tar -zxvf go1.24.4.linux-amd64.tar.gz -C /usr/local/ 配置環境 vim ~/.bashrc 在配置文件最后加上下面三行&#xff1a; # 設置GO語言的路徑 export GOROOT/usr/local/go # 當前go…

【模擬 貪心】B4207 [常州市賽 2021] 戰士|普及+

B4207 [常州市賽 2021] 戰士 題目背景 搬運自 http://czoj.com.cn/p/443。數據為民間數據。 題目描述 小 X \text X X 在玩一款操控戰士和怪物戰斗的游戲。戰士初始生命值為 iH \text{iH} iH 、初始攻擊力為 iA \text{iA} iA 。怪物只有一個&#xff0c;初始生命值為 H…

37-Oracle 23 ai Shrink Tablespace(一鍵收縮表空間)

小伙伴們有沒有經歷過&#xff0c;超大表和超大數據的導入后&#xff0c;數據被刪除了&#xff0c;然而空間遲遲不釋放&#xff0c;存儲添置又跟不上&#xff0c;業務空間告警的時候。收縮就很必須了&#xff0c;然而收縮需謹慎&#xff0c;數據大過天。DBMS_SPACE.SHRINK_TABL…