給代碼加個(gè)保險(xiǎn)箱!Kotlin getOrElse花式用法大揭秘
先來(lái)個(gè)小劇場(chǎng)
? 程序員小張:"我的App又閃退了!用戶輸入了個(gè)不存在的索引..."
? 隔壁老王:"用getOrElse
??!比try-catch
優(yōu)雅100倍!"
? 小張:"還有這種摸魚神器?"
這個(gè)函數(shù)有點(diǎn)東西
getOrElse
就像你的代碼保鏢——當(dāng)你要從集合里拿東西時(shí):? 能拿到 → 直接給你想要的? 拿不到 → 掏出你事先準(zhǔn)備的Plan B
舉個(gè)栗子
val snackCabinet = listOf("辣條", "薯片", "可樂(lè)")
fun main() {
// 正常情況
println(snackCabinet.getOrElse(1) { "空氣" }) // 輸出:薯片
// 作死情況
println(snackCabinet.getOrElse(10) {
"第10個(gè)柜子是老板藏的私房錢,別碰!"
}) // 輸出:第10個(gè)柜子是老板藏的私房錢,別碰!
}
三大必殺技
1?? 數(shù)組/列表的防崩神器
val temperatureData = arrayOf(23, 25, 22)
fun getTemperature(index: Int): Any {
// 常規(guī)寫法 vs getOrElse
// if (index < temperatureData.size) temperatureData[index] else "N/A"
return temperatureData.getOrElse(index) { "Sensor Error" }
}
fun main() {
println(getTemperature(5)) // 輸出:Sensor Error
}
2?? Map的萬(wàn)能鑰匙
val employeeBonuses = mutableMapOf("老王" to 5000)
fun calculateBonus(name: String): Int {
// 當(dāng)你要找不存在的鍵時(shí)...
return employeeBonuses.getOrElse(name) {
// 動(dòng)態(tài)計(jì)算默認(rèn)值
(employeeBonuses.values.average() * 0.5).toInt()
}
}
fun main() {
println(calculateBonus("Reathin")) // 輸出:2500 (因?yàn)橹挥欣贤跻粋€(gè)人)
}
3?? 超智能的默認(rèn)值工廠
默認(rèn)值可以是個(gè)函數(shù)
!這意味著你可以:
val stockPrices = listOf(18.5, 19.3, 20.1)
fun fetchStock(index: Int): Double {
return stockPrices.getOrElse(index) {
// 實(shí)時(shí)獲取最新股價(jià)
Random.nextDouble(15.0, 25.0)
}
}
fun main() {
println("%.2f".format(fetchStock(10))) // 輸出類似:21.34
}
靈魂拷問(wèn)區(qū)
? ?問(wèn):和?:空合并操作符有啥區(qū)別?
? ??答:getOrElse能根據(jù)索引/鍵動(dòng)態(tài)生成默認(rèn)值,更靈活!
? ?問(wèn):會(huì)影響性能嗎?
? ??答:lambda表達(dá)式會(huì)被inline處理,放心用!
實(shí)戰(zhàn)套路
場(chǎng)景1:表單校驗(yàn)
data class UserForm(val name: String, val age: Int)
fun parseForm(inputs: List<Any>): UserForm {
return UserForm(
name = inputs.getOrElse(0) { "Reathin" }.toString(),
age = (inputs.getOrElse(1) { 18 } as? Int) ?: 18
)
}
fun main() {
println(parseForm(listOf("Reathin"))) // 輸出:UserForm(name=Reathin, age=18)
}
場(chǎng)景2:游戲開(kāi)發(fā)
val inventory = arrayOf("藥水", "寶劍")
fun useItem(slot: Int) {
val item = inventory.getOrElse(slot) {
throw IllegalArgumentException("空氣怎么用?")
}
println("使用 $item")
}
fun main() {
useItem(3) // 拋出異常:IllegalArgumentException
}
專家級(jí)騷操作
套娃寫法
// 如果連默認(rèn)值都可能不存在?再套一層!
fun getDeepValue() = listOf(1, 2, 3).getOrElse(5) {
(10..20).filter { it % 3 == 0 }
.getOrElse(4) { -1 }
}
fun main() {
println(getDeepValue()) // 輸出:-1
}
結(jié)合其他函數(shù)
// 先過(guò)濾再獲取,雙保險(xiǎn)!
fun processData() = (1..10)
.filter { it % 2 == 0 }
.map { it * 10 }
.getOrElse(5) { listOf(-1) }
fun main() {
println(processData()) // 輸出:[20, 40, 60, 80, 100, -1]
}
避坑指南
?? 注意:當(dāng)Map的值為null時(shí),依然會(huì)觸發(fā)默認(rèn)值!
val nullableMap = mapOf("key" to null)
println(nullableMap .getOrElse("key") { "我是備胎" }) // 輸出:我是備胎
總結(jié)大禮包
getOrElse
的正確打開(kāi)方式:
? 把可能爆炸的操作換成安全模式
? 默認(rèn)值可以玩出花樣(計(jì)算值、拋異常、調(diào)用函數(shù)...)
? 讓代碼像德芙一樣絲滑~
下次遇到索引越界/鍵不存在時(shí),記得給你的代碼上個(gè)保險(xiǎn)!快去試試這些騷操作吧~