網站首頁 編程語言 正文
1.apply 函數
apply函數可以看做是一個配置函數。針對apply函數的調用者做一些配置,并把調用者返回。
示例:下面apply的調用者是file,調用完之后,返回的還是file,并在apply函數中,針對file做了一些配置。
val file = File("d:\\hello.txt").apply {
setWritable(true)
setReadable(true)
setExecutable(false)
}
apply源碼分析:
1)apply 用inline修飾,是一個內聯函數。
2)定義了一個<T>泛型,T.apply 調用者就是T,:T apply返回的類型也是T
上面的file就相當于T
3)再看apply的參數:block: T.() -> Unit。這是一個匿名函數,T.()->說明接收的是T的函數返回的是Unit類型。
4)在apply內部 調用了這個匿名函數block()也就是T的
5)return this,就是apply 的返回值,返回的是當前調用apply函數的對象。
public inline fun <T> T.apply(block: T.() -> Unit): T {
block()
return this
}
2.let 函數
let函數會把調用者作為參數傳到lambda表達式里,可以用it來代替它使用。函數執行完畢,lambda表達式返回的結果,就是let函數返回的結果。
val hello = "Hello world".let {
it.replace("world","kotlin")
}
//打印結果 Hello kotlin
println(hello)
看下let函數的定義:
1)let函數也是一個內聯函數。
2)定義了兩個泛型<T,R> T.let(),說明T是let的調用者。
3)block: (T) -> R 說明let接收的是一個匿名函數,匿名函數的參數是T,返回值是R
4): R 說明let函數的返回在也是R,也就是定義的匿名函數的返回值。
5)return block(this) 把當前調用者當做參數傳進來,lambda執行結果返回
上面的示例,調用let后,會把調用者當做參數傳遞到匿名函數也就是lambda中,并把lambda的執行結果,當做是let的結果返回。
inline fun <T, R> T.let(block: (T) -> R): R {
return block(this)
}
3.run函數
run函數和apply差不多,可以給調用者做配置。唯一的差別是apply返回的是當前調用者對象,而run返回的是lambda執行的結果。
val text = File("d:\\hello.txt").run {
setWritable(true)
setReadable(true)
setExecutable(false)
readText()
}
println(text)
run函數分析:
1)run函數也是一個內聯函數。
2)有兩個泛型<T,R>,T是當前調用者,R是返回值
3)run接收一個lambda :block: T.() -> R 調用T的方法,并且把執行結果返回
4): R lambda的執行結果,就是run函數的執行結果。我們知道lambda默認會把最后一行的結果返回。
5)return block() 返回lambda的執行結果
inline fun <T, R> T.run(block: T.() -> R): R {
return block()
}
4.with 函數
with函數是run的變體,他們的功能是一樣的。唯一的不同是調用方式,調用with時,第一個參數需要傳入一個值參。
val hello = "Hello World"
val h2 = with(hello) {
replace("World", "Kotlin")
}
println(h2)
源碼分析:
with接收兩個參數,第一個是傳入的值參,第二個是一個lambda表達式。
inline fun <T, R> with(receiver: T, block: T.() -> R): R {
return receiver.block()
}
5.also
also函數和let函數類似,also也是把調用者作為參數傳遞給lambda,不同點是let返回的是lambda的執行結果,而also返回的是當前調用者對象,這點和apply類似。
這對這個特點,可以實現調用者的鏈式調用。
舉個簡單列子。
雖然對hello做了substring,但并不會改變hello的初始值。因為最后返回的還是調用者對象本身。
val hello = "Hello world".also {
println(it.count())
}.also{
println(it.substring(0,5))
}
println(hello)
源碼分析:
block: (T) -> Unit also接收一個lambda,這個lambda把調用者T當參數傳進來了,block(this)。
return this 又把當前對象返回回去了。
inline fun <T> T.also(block: (T) -> Unit): T {
block(this)
return this
}
6.takeIf
takeIf需要判斷lambda表達式中結果,如果true則返回調用者對象,如果是false,則返回null。
如果需要判斷某個條件是否滿足,再決定是否可以給變量賦值或執行某項任務時,takeIf就很好用。takeIf類似于if語句。
示例:如果flag為true,則給hello賦值“Hello world”。
如果flag為false,則返回null,但是后面又有一個?:判斷,就會給hello賦值“hello null”
var flag = false
val hello = "Hello world".takeIf { false } ?: "hello null"
println(hello)
源碼分析:
從if (predicate(this)) this else null可以看出,如果predicate(this)為true則返回調用者this否則返回null
inline fun <T> T.takeIf(predicate: (T) -> Boolean): T? {
return if (predicate(this)) this else null
}
通過源碼分析,takeIf也會把調用者T當做參數傳到lambda中,這樣我們在lambda中就可以針對調用者做判斷,滿足某些條件則返回調用者對象,如果不滿足,則返回null。
val hello = "Hello world".takeIf {
it.count() > 15
} ?: "hello kotlin world"
println(hello)
7.takeUnless
takeUnless剛好和takeIf相反,只有給定條件為false時,才會返回takeUnless調用者對象,否則返回null。
val hello = "Hello world".takeUnless {
it.count() > 15
} ?: "hello kotlin world"
println(hello)
源碼:
if (!predicate(this)) 剛好和takeIf中的相反。
inline fun <T> T.takeUnless(predicate: (T) -> Boolean): T? {
return if (!predicate(this)) this else null
}
原文鏈接:https://blog.csdn.net/niuyongzhi/article/details/126527605
相關推薦
- 2022-06-14 GO語言協程創建使用并通過channel解決資源競爭_Golang
- 2022-08-19 淺談Redis6.x io事件驅動模型
- 2022-08-14 淺談Python任務自動化工具Tox基本用法_python
- 2022-01-02 前端生成二維碼及把頁面轉為圖片保存到本地
- 2023-10-11 nginx:connect() failed (111: Connection refused) w
- 2022-04-30 C#實現鼠標消息捕獲_C#教程
- 2022-06-16 HTTP服務壓力測試工具及相關術語講解_Golang
- 2023-02-05 Flutter實現固定header底部滑動頁效果示例_Android
- 最近更新
-
- window11 系統安裝 yarn
- 超詳細win安裝深度學習環境2025年最新版(
- Linux 中運行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎操作-- 運算符,流程控制 Flo
- 1. Int 和Integer 的區別,Jav
- spring @retryable不生效的一種
- Spring Security之認證信息的處理
- Spring Security之認證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權
- redisson分布式鎖中waittime的設
- maven:解決release錯誤:Artif
- restTemplate使用總結
- Spring Security之安全異常處理
- MybatisPlus優雅實現加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務發現-Nac
- Spring Security之基于HttpR
- Redis 底層數據結構-簡單動態字符串(SD
- arthas操作spring被代理目標對象命令
- Spring中的單例模式應用詳解
- 聊聊消息隊列,發送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠程分支