把數(shù)值關(guān)進(jìn)籠子:用Kotlin的coerce三兄弟玩轉(zhuǎn)邊界控制
寫代碼就像玩策略游戲,總得給數(shù)值設(shè)定「安全區(qū)」。比如游戲角色的血量不能跌破0、奶茶甜度不能超過200%、文件體積不能突破存儲上限...今天教你用Kotlin自帶的三個「數(shù)值牢籠」優(yōu)雅解決邊界問題!
先看一段讓你血壓升高的代碼
// 傳統(tǒng)方式:用if/else給數(shù)值上枷鎖
fun processUserAge(age: Int): Int {
var result = age
if (age < 0) { // 第一道防線
result = 0
} else if (age > 120) { // 第二道防線
result = 120
}
return result
}
// 使用示例
println(processUserAge(-5)) // 輸出:0
println(processUserAge(130)) // 輸出:120
println(processUserAge(25)) // 輸出:25
這段代碼就像給數(shù)值套了三層防盜門:
? 檢查是否小于最小值 → 關(guān)進(jìn)地下室
? 檢查是否大于最大值 → 鎖上天臺
? 中間值才能安全通行
痛點(diǎn)暴擊:
? 邊界條件需要重復(fù)判斷
? 修改范圍時要同時調(diào)整兩處數(shù)字
? 處理浮點(diǎn)數(shù)時容易遺漏精度問題
Kotlin提供了三個非常實(shí)用的方法——coerceIn、coerceAtLeast 和 coerceAtMost,可以幫助我們更簡潔地實(shí)現(xiàn)這些功能。接下來,讓我們一起來看看這三位coerce兄弟的具體用法吧!
coerceIn:給數(shù)值上雙保險鎖
coerceIn(min, max)方法的作用是將一個數(shù)值限制在一個指定的范圍內(nèi)。如果數(shù)值超出了這個范圍,則返回相應(yīng)的邊界值。
場景:游戲角色的血量必須維持在0-100之間
var hp = 120
hp = hp.coerceIn(0, 100) // 超過上限直接鎖死
println("當(dāng)前血量:$hp") // 輸出:當(dāng)前血量:100
hp = -15
hp = hp.coerceIn(0, 100) // 跌破下限自動修正
println("瀕死保護(hù):$hp") // 輸出:瀕死保護(hù):0
隱藏技巧:范圍值可以動態(tài)計(jì)算,比如根據(jù)角色等級調(diào)整血量上限
val maxHp = level * 50
currentHp = currentHp.coerceIn(0, maxHp)
coerceAtLeast:設(shè)置數(shù)值底褲
coerceAtLeast(min)方法用于確保一個數(shù)值不小于某個最小值。如果數(shù)值小于最小值,則返回最小值;否則返回原數(shù)值。
場景:奶茶店小程序限制最低甜度為30%
fun setSweetness(percent: Int): Int {
return percent.coerceAtLeast(30) // 低于30自動補(bǔ)到最低值
}
println(setSweetness(25)) // 輸出:30
println(setSweetness(50)) // 輸出:50
實(shí)戰(zhàn)應(yīng)用:防止負(fù)數(shù)導(dǎo)致的bug,比如物品數(shù)量永遠(yuǎn)不會小于零:
var itemCount = -5
itemCount = itemCount.coerceAtLeast(0) // 強(qiáng)制歸零
coerceAtMost:給數(shù)值蓋天花板
coerceAtMost(max)方法則是用來確保一個數(shù)值不大于某個最大值。如果數(shù)值超過了最大值,則返回最大值;否則返回原數(shù)值。
場景:上傳圖片限制5MB以內(nèi)
fun checkImageSize(mb: Float): Float {
return mb.coerceAtMost(5f) // 超過5MB的自動壓縮標(biāo)記
}
println(checkImageSize(6.8f)) // 輸出:5.0
println(checkImageSize(3.2f)) // 輸出:3.2
組合技:動態(tài)計(jì)算文件體積上限,根據(jù)用戶會員等級調(diào)整:
val maxSize = if (isVip) 10f else 5f
fileSize = fileSize.coerceAtMost(maxSize)
進(jìn)階玩法:給自定義類型裝護(hù)欄
除了基本的數(shù)值類型,coerce系列方法還可以用于實(shí)現(xiàn)了Comparable接口的自定義類。
場景:游戲版本號控制系統(tǒng)(v1.0-v3.0)
// 自定義版本類
data class GameVersion(val major: Int, val minor: Int) : Comparable<GameVersion> {
overridefun compareTo(other: GameVersion): Int {
return when {
major != other.major -> major - other.major
else -> minor - other.minor
}
}
}
// 版本控制
val minVer = GameVersion(1, 0)
val maxVer = GameVersion(3, 0)
val current = GameVersion(4, 2)
val safeVer = current.coerceIn(minVer, maxVer)
println(safeVer) // 輸出:GameVersion(major=3, minor=0)
避坑指南
1. 范圍顛倒陷阱:coerceIn(100, 0)會導(dǎo)致崩潰,就像把護(hù)欄裝反了
val safeValue = 50.coerceIn(100, 0) // 拋出IllegalArgumentException
2. 浮點(diǎn)數(shù)精度問題:處理金額時推薦使用BigDecimal
val money = BigDecimal("15.5")
money.coerceIn(BigDecimal("10"), BigDecimal("20"))
3. 空值防御:處理可空類型時要先判空
val maybeNumber: Int? = null
maybeNumber?.coerceAtLeast(0) ?: 0
結(jié)論
coerce方法就像代碼界的智能護(hù)欄,既省時又美觀!
? 上限下限都要管 → coerceIn
? 防止數(shù)值穿地心 → coerceAtLeast
? 避免突破大氣層 → coerceAtMost
? 自定義類型要繼承Comparable接口
用好這三兄弟,讓你的代碼像裝了智能圍欄,既安全又優(yōu)雅!