2

因此,在我在 android (Kotlin) 中创建了许多枚举类之后,我了解到枚举在 android 中的空间效率不是很高。所以我试图找到另一种方法。我找到了枚举注释 - @StringDef。但是,Kotlin 似乎并不能很好地支持这一点,即使我将一些意想不到的东西传递给方法,也没有警告或错误消息。

所以要澄清我想要做什么:我有大量的常量字符串可以分类到不同的组(我将它们列在不同的枚举类中),并且在调用一些 setter 函数时,我希望调用者只从特定组中进行选择可以选择的东西。

例如:

enum class Cat (val breed: String){
    AMER_SHORTHAIR("American Shorthair"),
    SIAMESE("Siamese");
}
enum class Dog (val breed: String){
    GOLDEN_R("Golden Retriever"),
    POODLE("Poodle");
}
fun adopt(cat: Cat, dog: Dog){
    print("I adopted a "+cat.breed+" and a "+dog.breed)
}

在这种情况下,我只能选择猫作为第一个参数,狗作为第二个参数。有没有办法在不使用枚举的情况下执行这种类型安全的方法?

为了避免使用枚举,我可能需要将上述功能更改为:

const val AMER_SHORTHAIR = "American Shorthair"
const val SIAMESE = "Siamese"
const val GOLDEN_R = "Golden Retriever"
const val POODLE = "Poodle"
fun adopt(cat: String, dog: String){...}

这并不理想,因为我们可以得到当前实现中发生的各种拼写错误,这也是我首先切换到 enum 的原因。但总的来说,空间消耗 > 类型安全。因此,如果没有更好的方法,我将需要切换回来。

请让我知道是否有任何有效的方法来实现。我曾考虑过使用映射或列表,但是索引或访问字符串变得很麻烦,因为我需要将字符串映射到它们自己(这里没有硬编码字符串,除了第一个赋值,比如AMER_SHORTHAIR = "American Shorthair")。

谢谢。

4

2 回答 2

1

我同意@EpicPandaForce 的评论:你不应该以这种方式优化枚举。

也就是说,会有一个新功能:Kotlin 1.3 中的内联类( https://blog.jetbrains.com/kotlin/2018/07/see-whats-coming-in-kotlin-1-3-m1/) .

使用此新功能,您可以执行以下操作:

inline data class Cat(private val breed: String)
inline data class Dog(private val breed: String)

val AMER_SHORTHAIR = Cat("American Shorthair");
val SIAMESE = Cat("Siamese");

val GOLDEN_R = Dog("Golden Retriever");
val POODLE = Dog("Poodle");  

fun adopt(cat: Cat, dog: Dog){
    print("I adopted a "+cat.breed+" and a "+dog.breed)
} 

每当您使用此值时,编译器都会内联到原始字符串。

类型别名相比,编译器能够检查内联类的原始类型。

于 2018-08-01T06:46:43.557 回答
0

我喜欢使用 Sealed 类而不是 Enums;它比普通课程提供了一些额外的好处;更多关于这里

像这样的东西;

class LoggingBehaviour @JvmOverloads constructor(private val logLevel: LogLevel = Debug) {
    fun log(tag: String, message: String) {
        when (logLevel) {
            is Error -> Log.e(tag, message)
            is Warn -> Log.w(tag, message)
            is Info -> Log.i(tag, message)
            is Debug -> Log.d(tag, message)
            is Verbose -> Log.v(tag, message)
        }
    }
}

sealed class LogLevel
object Error : LogLevel()
object Warn : LogLevel()
object Info : LogLevel()
object Debug : LogLevel()
object Verbose : LogLevel()

也可以使用 IntDef 和 StringDef 等注释。更多这里

于 2020-07-23T11:13:37.500 回答