【发布时间】:2021-04-30 09:21:01
【问题描述】:
Kotlin 有类型别名,在你想要一个好的命名时非常方便。但是,在某些情况下,您希望有一个比别名多一点的类型别名,您希望它强制执行实际的编译时检查,而不需要创建新类。
这就是我想要实现的目标:
typealias MyNum = Int
fun isMagical(num: MyNum) = num == 42
fun main() {
// Should fail/warn
isMagical(42)
// Should pass
isMagical(42 as MyNum)
// Should fail/warn
val x = 3
isMagical(x)
// Should pass
val y: MyNum = 3
isMagical(y)
}
我知道我可以使用内联类来实现这一点,但我需要检查其中的许多类型,并且不想为每个类型创建一个类。
是否可以通过注释来实现?喜欢:
@Target(AnnotationTarget.TYPEALIAS)
annotation class StrongType
@StrongType
typealias MyNum = Int
然后让注释处理器进行检查?
我想做类似安卓的事情@IntDef:
// Android way (performant but needs to manually annotates methods and list the options in the annotation)
@Retention(SOURCE)
@IntDef({NAVIGATION_MODE_STANDARD, NAVIGATION_MODE_LIST, NAVIGATION_MODE_TABS})
public @interface NavigationMode {}
public static final int NAVIGATION_MODE_STANDARD = 0;
public static final int NAVIGATION_MODE_LIST = 1;
public static final int NAVIGATION_MODE_TABS = 2;
// Enum way (not performant)
enum class NavMode constructor(val value: Int){
STANDARD(0),
LIST(1),
TABS(2)
}
// Inline class (performant but generating a lot of code)
inline class NavMode(val value: Int) {
companion object {
val STANDARD = NavMode(0)
val LIST = NavMode(1)
val TABS = NavMode(2)
}
}
// This is what I would like: performant, type check in methods without annotating them, clean code
@StrongType
typealias NavMode = Int
const val STANDARD: NavMode = 0
const val LIST: NavMode = 1
const val TABS: NavMode = 2
请注意,这不是我真正的用例,我有很多这样的枚举要创建,同时保持高性能(就像在 android API 中一样)。 您认为实现我想要的最可行的方法是什么? 谢谢
【问题讨论】:
-
可能不是您正在寻找的响应,但您建模数据的方式可能是问题所在。如果您需要经常进行
isMagical检查,我觉得您需要一个类型,因为检查可以是类型的一部分。如果只有某些值是“特殊的”,那么也许枚举会更合适。只是一个想法。 -
我有效率限制和很多这样的枚举要创建,这对我来说并不是一个合适的解决方案
标签: java class kotlin annotations type-alias