Kotlin枚举:引用从其调用的任何枚举对象的函数

时间:2018-08-02 12:05:19

标签: enums kotlin

我正在尝试从枚举print()中的对象编写一个可以如下调用的枚举函数Molecule

Molecule.HYDROGEN_MOLECULE.print()
myMolecule.print()

我不想为函数提供特定的枚举对象:

Molecule.print(Molecule.HYDROGEN)

但是,当我在Molecule中创建函数时,尝试引用MolecularFragment的列表时会出现错误。

我需要在print()中使用哪种语法来使类似myMolecule.print()的东西引用该特定枚举对象的MolecularFragment列表?

enum class Molecule (val MolecularFragments : List<MolecularFragment> = emptyList()) {

    HYDROGEN_MOLECULE(listOf(MolecularFragment.H2)),

    WATER_MOLECULE(listOf(MolecularFragment.H2O)),
    // ...
    HEXANE_MOLECULE(listOf(MolecularFragment.CH3, MolecularFragment.CH2));

    fun print() {

        **var x : List<MolecularFragment> = Molecule.MolecularFragments**
        x.forEach() {
            println("$it")
        }
        println(" --- ${Molecule.toString()}")
    }
}

3 个答案:

答案 0 :(得分:1)

我想这正是您想要的:

enum class MolecularFragment { H2, H2O, CH3, CH2 }

enum class Molecule (val molecularFragments : List<MolecularFragment> = emptyList()) {

    HYDROGEN_MOLECULE(listOf(MolecularFragment.H2)),

    WATER_MOLECULE(listOf(MolecularFragment.H2O)),

    HEXANE_MOLECULE(listOf(MolecularFragment.CH3, MolecularFragment.CH2));

    fun print() {
        molecularFragments.forEach(::println)
        println("${this::class.java.toString()}")
    }
}

fun main(args: Array<String>) {
    Molecule.HYDROGEN_MOLECULE.print()
}

一些注意事项:

  • 您用双星号突出显示的行甚至没有编译。
  • 您可以使用函数引用来打印元素。
  • 您不需要先将属性molecularFragments放在变量中。
  • 下次,请指定MolecularFragment,以便代码可以立即运行。

答案 1 :(得分:0)

我将使用与此类似的方法:

enum class MyType(val subTypes: List<String>) {

    FIRST_TYPE(listOf("one", "two")),
    SECOND_TYPE(listOf("three", "four"));
}

//Honestly his method could be moved in some util .kt file
    fun printOneType(myType: MyType) {
        myType.subTypes.forEach { print(it.toString()) }
    }

如果您无法在枚举的内部集合中打印子对象,则可能无法很好地实现其toString()或其他util方法-只是一个选择。

编辑。主题入门问题的解决方案要简单得多。无论如何,如果是枚举的内部集合,则可以执行以下操作:

enum class MyType(val otherTypes: List<OtherType>) {

    FIRST_TYPE(listOf(OtherType.FIRST)),
    SECOND_TYPE(listOf(OtherType.SECOND));
}

//Honestly his method could be moved in some util .kt file
fun printOneType(myType: MyType) {
        myType.otherTypes.forEach { print(it.name) }
    }
}

答案 2 :(得分:0)

@marstran已在注释中指出:从您标记的行中删除Molecule,使其看起来像:

var x : List<MolecularFragment> = MolecularFragments

,或者如果您愿意:

var x : List<MolecularFragment> = this.MolecularFragments

枚举类方法访问this枚举值的值,而不是单例或静态方法。

或者,您也可以提供通用扩展功能,该功能允许随时打印任何枚举:

fun <T : Enum<T>> Enum<T>.printIt() = toString().also(::println)

通过这种方式,您只需要覆盖toString()方法,甚至可以将该toString方法用于其他目的,例如覆盖示例:

enum class Molecule ... {
  // ...
  override fun toString(): String {
      return super.toString() + ": $molecularFragments"
  }
}

..以及@marstran也指出:Kotlin中最常见的代码约定是以小写字母开头的属性。