持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第2天,点击查看活动详情
前言
大家可能会说,when 还不简单,看我操作:
val num = 1
when(num){
0 -> {}
1 -> {}
2 -> {}
}
复制代码
em...这不是出现了魔术数字了吗?
身为有那么一点点追求的程序员👨🏻💻,还得想下,怎么写更合适。
这里,我总结了四种方式,并列出相应的场景供大家参考。
- 常量字符串
- 常量数字
- 枚举
- sealed class
常量字符串
最简单的方式就是:
object StatisticKey {
const val LOGIN = "login"
const val REGISTER = "register"
}
复制代码
val key = StatisticKey.LOGIN
when(key){
StatisticKey.LOGIN -> {}
StatisticKey.REGISTER -> {}
}
复制代码
但是,这样叠加下去,当 key 越来越多,模块越来越多就会显得很混乱,不太可能全部每个 module 都依赖同一个 StatisticKey Module,应该每个 Module 都有自己的埋点,互不干扰,但又能统一为埋点。
所以,在这时,我们可以将 StatisticKey 抽取出来放到 Common Module 中,
object StatisticKey
复制代码
然后在每个 Module 中添加相应的扩展变量,并声明相应类型,例如,我在用户模块进行书写:
val StatisticKey.User: UserStatisticKey
get() = UserStatisticKey
object UserStatisticKey {
const val LOGIN = "login"
const val REGISTER = "register"
}
复制代码
这时就可以这样使用:
val key = StatisticKey.User.LOGIN
when(key){
StatisticKey.User.LOGIN -> {}
StatisticKey.User.REGISTER -> {}
}
复制代码
常量数字
常量数字跟常量字符串的使用非常相似,其实就是把声明的值改为数字而已,例如:
val StatisticKey.User: UserStatisticKey
get() = UserStatisticKey
object UserStatisticKey {
const val LOGIN = 1
const val REGISTER = 2
}
复制代码
但是,对于可递进的判断条件,常量数字就能够产生很有效的作用,例如我们对日志进行统一管理:
object LogUtils {
const val VERBOSE = 1
const val DEBUG = 2
const val INFO = 3
const val WARN = 4
const val ERROR = 5
var limitLog = ERROR
fun logW(msg: String){
if (limitLog <= WARN){
Log.w(null, msg)
}
}
fun logE(msg: String){
if (limitLog <= ERROR){
Log.e(null, msg)
}
}
}
复制代码
就能够很方便进行条件判断。
枚举
枚举的使用也非常简单:
enum class User{
LOGIN, REGISTER
}
复制代码
val value = User.LOGIN
when(value){
User.LOGIN -> {}
User.REGISTER -> {}
}
复制代码
不过,枚举有一个好处,就是带值。可以预先存储一些值,在必要的时候,再拿出来,并且,并不是只能存一个,可以存多个,主要看你怎么声明:
enum class User(val type: Int, val type2: Int){
LOGIN(1, 1), REGISTER(2, 2)
}
复制代码
取出的时候,调用 User.LOGIN.type
或者 User.LOGIN.type2
即可。
sealed class
虽然枚举是可以带值的,但是值的类型基本都是固定的,而且还是预存的值,这往往不能满足更灵活的需求,例如在做下载状态判断的时候,不同的状态是需要不同的返回值的。而这时,我们就可以考虑使用 sealed class
。
sealed class DownloadStatus{
object Start : DownloadStatus()
data class Downloading(val progress: Int) : DownloadStatus()
data class Success(val path: String) : DownloadStatus()
data class Failed(val error: Throwable) : DownloadStatus()
}
复制代码
在条件判断的时候,我们就可以这样:
val status : DownloadStatus = DownloadStatus.Downloading(1)
when(status){
is DownloadStatus.Start -> {}
is DownloadStatus.Downloading ->{
println(status.progress)
}
is DownloadStatus.Success ->{
println(status.path)
}
is DownloadStatus.Failed ->{
println(status.error)
}
}
复制代码
这样我们就可以根据不同状态获取得到不同的值了。
欢迎各位大佬进行补充。