Kotlin中如何根据另一常量值为常量赋值?
Kotlin环境区分常量集的问题解决
问题场景
想在本地测试和服务器运行时使用不同的常量集,尝试用以下代码赋值:
const val FOO = false const val BAR = if (FOO) 1L else 2L
但编译器报错,提示该if-else表达式不被视为常量。
报错原因
Kotlin中const val要求右侧必须是编译期可确定的常量表达式,哪怕判断条件是const val,if-else分支结构本身不属于编译器认可的常量表达式类型——编译器不会在编译阶段主动推导分支结果并固化为常量,因此会报错。
可行实现方案
1. 利用构建变体生成编译期常量(推荐)
如果是Android项目,直接通过Gradle的构建类型(debug/release)生成对应常量:
android { buildTypes { debug { // 本地测试用的常量 buildConfigField "long", "BAR", "1L" } release { // 服务器运行用的常量 buildConfigField "long", "BAR", "2L" } } }
编译后直接通过BuildConfig.BAR调用,这是标准的编译期常量,能满足所有需要常量的场景(包括注解参数)。
如果是纯Kotlin非Android项目,可通过Gradle源码集区分:
- 创建
src/debug/kotlin和src/release/kotlin目录 - 在两个目录下分别创建
Constants.kt:
debug版本:
release版本:const val BAR = 1L
Gradle会根据构建类型自动加载对应目录的代码,编译后得到对应常量。const val BAR = 2L
2. 改用运行期不可变常量
如果不需要编译期常量的特性(比如不用在注解里),可以用@JvmField标记普通val,实现运行期不可变的效果:
const val FOO = false @JvmField val BAR = if (FOO) 1L else 2L
这个方案无需修改构建配置,简单快捷,但BAR不是编译期常量,不能用于注解参数等要求编译期值的场景。
内容的提问来源于stack exchange,提问作者Kanashimi
相关产品推荐
相关产品推荐

