Kotlin里兩個(gè)偷懶神器:lateinit和by lazy簡單易懂解釋
有沒有經(jīng)歷過這樣的絕望時(shí)刻???
? 寫代碼時(shí)對(duì)象像約會(huì)遲到,總在需要它的時(shí)候不見蹤影
? 想先聲明變量后面再賦值,卻被編譯器瘋狂報(bào)錯(cuò)追殺
? 每次初始化都要寫一堆判空邏輯,代碼腫得像泡發(fā)的饅頭
Kotlin
早就看穿了這一切,于是掏出了兩把金鑰匙:lateinit和by lazy。這哥倆一個(gè)像會(huì)賒賬的便利店老板,一個(gè)像精打細(xì)算的存錢罐,專治各種初始化不服。接下來就帶你看透它們的套路,保準(zhǔn)你學(xué)完直拍大腿:"早該用這招了!"
lateinit(先欠著型)
這玩意兒咋用?
// 聲明個(gè)按鈕但先不裝(就像網(wǎng)購下單但沒付款)
lateinit var 我的按鈕: Button
// 等頁面加載好了再裝按鈕(確認(rèn)收貨)
override fun onCreate(...) {
我的按鈕 = findViewById(R.id.按鈕)
}
必看說明書
? 只能欠對(duì)象
:比如String、View這些大件,不能欠Int這種小東西(系統(tǒng)不讓你欠5塊錢)
? 必須還債
:用之前不初始化?直接閃退報(bào)錯(cuò)!就像吃飯不給錢會(huì)被老板抓住
? 查崗功能
:可以用::我的按鈕.isInitialized看看有沒有裝好按鈕
什么時(shí)候用?
? Android里綁定控件(頁面沒加載完時(shí)按鈕確實(shí)不存在)
? 測(cè)試的時(shí)候臨時(shí)造數(shù)據(jù)
? 重點(diǎn):你100%確定后面會(huì)填坑的情況!
by lazy(拖延癥型)
典型用法
// 配置信息(等到有人要看了才去查檔案)
val 用戶配置 by lazy {
println("正在翻檔案柜...")
loadConfig() // 假裝這里要查數(shù)據(jù)庫
}
// 第一次訪問時(shí)才干活
println(用戶配置) // 這里才會(huì)執(zhí)行上面的代碼
println(用戶配置) // 直接拿上次的結(jié)果
核心賣點(diǎn)
? 自動(dòng)拖延
:不叫你就不動(dòng)(省電模式)
? 只干一次活
:第一次干活后就把結(jié)果存起來(老油條行為)
? 啥都能拖
:基本類型、對(duì)象、可空類型通吃
? 安全模式
:默認(rèn)不怕多線程搶著用(當(dāng)然也能調(diào)成單身狗模式)
適用場景
? 加載大文件(比如游戲資源)
? 網(wǎng)絡(luò)請(qǐng)求配置
? 需要復(fù)雜計(jì)算的數(shù)據(jù)
? 所有能拖到最后一刻干的事
對(duì)照表(飯圈版)
lateinit | by lazy | |
性格 | 急性子(必須手動(dòng)給) | 懶癌晚期(自動(dòng)拖延) |
戶口 | 必須是var(能改嫁) | 必須是val(從一而終) |
安全 | 容易翻車(忘初始化就完蛋) | 自帶安全氣囊(默認(rèn)線程安全) |
特長 | 適合動(dòng)態(tài)變化的東西 | 適合一成不變的老古董 |
選擇困難癥急救包
選lateinit:
? 東西需要變來變?nèi)ィū热鐒?dòng)態(tài)更換按鈕)
? 你能控制什么時(shí)候填坑(比如在onCreate里)
? 不能用val的情況(比如要重新綁定控件)
選by lazy:
? 東西生下來就定型(比如APP配置)
? 初始化很費(fèi)勁(比如要讀大文件)
? 想自動(dòng)防呆(防止重復(fù)初始化)
防呆小貼士
lateinit翻車現(xiàn)場:
lateinit var 還沒準(zhǔn)備好的數(shù)據(jù): String
fun 作死() { println(還沒準(zhǔn)備好的數(shù)據(jù)) } // 閃退!
by lazy保命技巧:
val 保命數(shù)據(jù) by lazy(LazyThreadSafetyMode.NONE) {
// 單身狗模式(效率更高但只能單線程用)
}
終極總結(jié)
? lateinit
= 先畫個(gè)餅,記得后面烙熟?。ㄟm合會(huì)變的東西)
? by lazy
= 打死不早做準(zhǔn)備,但保證隨叫隨到!(適合不變的東西)
記住這兩招,Kotlin寫代碼能省一半力氣!用的時(shí)候悠著點(diǎn),別把餅畫太大最后烙不熟就行~