别再手写 if/else 判断了!赶紧来掌握 Kotlin 的 coerce 三兄弟吧

在日常开发中,我们常常需要对数值进行范围限制,比如限制用户输入的年龄在 0~120 之间,又或者限制图片透明度在 0f ~1f 之间。这类场景中,我们第一反应会写出类似这样的代码:

kotlin 复制代码
val age = if (inputAge < 0) 0 else if (inputAge > 120) 120 else inputAge

虽然功能上没毛病,但写多了会不会觉得还是有些繁琐?其实 Kotlin 已经为我们提供了优雅的解决方案:coerceIn、coerceAtLeast 和 coerceAtMost,合称为 coerce 三兄弟 。上述代码用coerceIn来写就会变成:inputAge.coerceIn(0,120),怎么样,是不是更简洁一些。

coerce 三兄弟简介

这个coerce单词还挺别捏,特意查了下词典:

来跟我读:kou-e-si,分成三节来看还简单点:co-er-ce

1、coerceIn(min, max) 限制数值在给定范围之内,超出则返回边界值。使用示例如:val clamped = value.coerceIn(min, max)

2、coerceAtLeast(min) 确保值不小于指定最小值,小于则返回最小值。如:val atLeast = value.coerceAtLeast(min)

3、coerceAtMost(max) 确保值不大于指定最大值,大于则返回最大值。如:val atMost = value.coerceAtMost(max)

使用示例对比

1、假设正在开发一个视频播放器,需要控制播放速度(范围为 0.5x 到 2.0x):

使用coerceIn 对应的 if/else 实现
val speed = inputSpeed.coerceIn(0.5f, 2.0f) val speed = if (inputSpeed < 0.5f) 0.5f else if (inputSpeed > 2.0f) 2.0f else inputSpeed

2、再比如限制用户昵称长度最少为 2 个字符:

使用coerceAtLeast 对应的 if/else 实现
val minLength = nickname.length.coerceAtLeast(2) val minLength = if (nickname.length < 2) 2 else nickname.length

3、限制上传图片不能超过 5MB:

使用coerceAtMost 对应的 if/else 实现
val fileSize = image.sizeInMb.coerceAtMost(5) val fileSize = if (image.sizeInMb > 5) 5 else image.sizeInMb

进阶用法:自定义类型也能用

coerceXXX 方法不仅适用于 Int、Float、Double这些基本类型,还可以用于实现了 Comparable 接口的自定义类,源码如下:

kotlin 复制代码
//T.coerceAtLeast
public fun <T : Comparable<T>> T.coerceAtLeast(minimumValue: T): T {
    return if (this < minimumValue) minimumValue else this
}

//T.coerceAtMost
public fun <T : Comparable<T>> T.coerceAtMost(maximumValue: T): T {
    return if (this > maximumValue) maximumValue else this
}

//T.coerceIn
public fun <T : Comparable<T>> T.coerceIn(minimumValue: T?, maximumValue: T?): T {
    if (minimumValue !== null && maximumValue !== null) {
        if (minimumValue > maximumValue) throw IllegalArgumentException("Cannot coerce value to an empty range: maximum $maximumValue is less than minimum $minimumValue.")
        if (this < minimumValue) return minimumValue
        if (this > maximumValue) return maximumValue
    }
    else {
        if (minimumValue !== null && this < minimumValue) return minimumValue
        if (maximumValue !== null && this > maximumValue) return maximumValue
    }
    return this
}

示例:

kotlin 复制代码
data class Version(val code: Int) : Comparable<Version> {
    override fun compareTo(other: Version): Int = this.code - other.code
}

val v1 = Version(1)
val v2 = Version(5)
val v3 = Version(10)

val current = Version(7)
val clamped1 = current.coerceIn(v1, v3)
val clamped2 = current.coerceIn(v1, v2)
val clamped3 = current.coerceIn(v2, v3)

Log.d("test", "$clamped1,$clamped2,$clamped3") 
//输出:Version(code=7),Version(code=5),Version(code=7)

总结

语法 含义 示例 等价逻辑
x.coerceAtLeast(min) 限制最小值 (-5).coerceAtLeast(0) → 0 if (x < min) min else x
x.coerceAtMost(max) 限制最大值 150.coerceAtMost(100) → 100 if (x > max) max else x
x.coerceIn(min, max) 限制值在区间内 150.coerceIn(0, 100) → 100, -20.coerceIn(0, 100) → 0 min(max(x, min), max)

使用 coerceIn、coerceAtLeast 和 coerceAtMost,可以大大简化常见的范围判断逻辑,提升代码的可读性与优雅度。告别繁琐的 if/else,让 Kotlin 的扩展函数替你完成繁重的边界控制!

别再手写判断了,是时候把 coerce 三兄弟收入囊中了!

相关推荐
用户2018792831679 小时前
Android黑夜白天模式切换原理分析
android
芦半山9 小时前
「幽灵调用」背后的真相:一个隐藏多年的Android原生Bug
android
卡尔特斯10 小时前
Android Kotlin 项目代理配置【详细步骤(可选)】
android·java·kotlin
ace望世界10 小时前
安卓的ViewModel
android
ace望世界10 小时前
kotlin的委托
android
CYRUS_STUDIO12 小时前
一文搞懂 Frida Stalker:对抗 OLLVM 的算法还原利器
android·逆向·llvm
zcychong12 小时前
ArrayMap、SparseArray和HashMap有什么区别?该如何选择?
android·面试
CYRUS_STUDIO13 小时前
Frida Stalker Trace 实战:指令级跟踪与寄存器变化监控全解析
android·逆向
ace望世界18 小时前
android的Parcelable
android
顾林海18 小时前
Android编译插桩之AspectJ:让代码像特工一样悄悄干活
android·面试·性能优化