用Kotlin的digitToIntOrNull玩轉(zhuǎn)字符轉(zhuǎn)換
舉個栗子??:你遇到過這些尷尬嗎?
當(dāng)你在解析驗證碼時遇到字符'G',或者處理用戶輸入時收到一個'?',是不是經(jīng)常要手寫一堆if-else來檢查字符合法性?現(xiàn)在試試這個神奇函數(shù):
fun parseCode(input: Char): Int? {
return input.digitToIntOrNull() // 一行代碼搞定驗證
}
digitToIntOrNull 是 Kotlin 標(biāo)準(zhǔn)庫的一部分,位于 kotlin.text 包下。它有兩個主要的用法:
- 默認(rèn)十進(jìn)制轉(zhuǎn)換:直接將一個字符轉(zhuǎn)換為十進(jìn)制整數(shù)。如果字符不是有效的十進(jìn)制數(shù)字,則返回 null。
- 指定進(jìn)制轉(zhuǎn)換:將一個字符轉(zhuǎn)換為指定進(jìn)制(radix)下的整數(shù)。如果字符在該進(jìn)制下無效,則返回 null。需要注意的是,進(jìn)制范圍必須在 2 到 36 之間,否則會拋出異常。
這個函數(shù)有多智能?
想象你有個全能驗鈔機(jī),不僅能識別人民幣,還能自動切換美元、歐元,甚至能檢測假幣。digitToIntOrNull就是代碼世界的智能驗鈔機(jī):
基礎(chǔ)模式(十進(jìn)制偵探)
println('7'.digitToIntOrNull()) // 輸出7 → 正經(jīng)數(shù)字
println('??'.digitToIntOrNull()) // 輸出null → 表情包退散!
進(jìn)階模式(進(jìn)制變形金剛)
// 十六進(jìn)制模式
println('F'.digitToIntOrNull(16)) // 輸出15 → 十六進(jìn)制的寵兒
println('G'.digitToIntOrNull(16)) // 輸出null → 超標(biāo)的字母
// 三十二進(jìn)制大挑戰(zhàn)
println('Z'.digitToIntOrNull(32)) // 輸出31 → 字母天花板
println('a'.digitToIntOrNull(32)) // 輸出10 → 大小寫通吃
避坑指南?:這些情況會翻車
① 二進(jìn)制遇到情場浪子
println('2'.digitToIntOrNull(2)) // null → 二進(jìn)制只認(rèn)0和1
② 全角字符的cosplay
val fullWidthA = 'A' // 全角A(Unicode:\uFF21)
println(fullWidthA.digitToIntOrNull(16)) // 輸出10 → 偽裝成功!
③ 希臘字母的悲劇
println('β'.digitToIntOrNull(36)) // null → 只認(rèn)拉丁字母
示例:用這個函數(shù)寫個進(jìn)制轉(zhuǎn)換
fun convertToDecimal(char: Char, base: Int): String {
return char.digitToIntOrNull(base)?.let {
"『$char』在${base}進(jìn)制中等于 $it"
} ?: "?? 警報!『$char』在${base}進(jìn)制里是冒牌貨"
}
fun main() {
println(convertToDecimal('L', 20)) // → 20進(jìn)制中L=18
println(convertToDecimal('喵', 36)) // → 觸發(fā)警報
}
冷知識:為什么進(jìn)制上限是36?
因為拉丁字母(26個) + 數(shù)字(10個) = 36個符號,剛好可以覆蓋所有情況。想挑戰(zhàn)更高進(jìn)制?除非你打算用emoji當(dāng)數(shù)字符號??
什么時候認(rèn)為字符是有效的數(shù)字?
fun Char.digitToIntOrNull(radix: Int): Int?
? 如果字符是常規(guī)的十進(jìn)制數(shù)字(0-9),那么它自然是有效的。
? 如果字符是大寫或小寫的拉丁字母(A-Z 或 a-z),并且其編碼值小于 radix + 'A'.code - 10 或 radix + 'a'.code - 10,那么它也是有效的。
? 全角拉丁字母(\uFF21-\uFF3A 或 \uFF41-\uFF5A)同樣適用上述規(guī)則。