代码之家  ›  专栏  ›  技术社区  ›  iForests

“when”表达式必须是穷举表达式使用适配器时出错

  •  0
  • iForests  · 技术社区  · 6 年前

    class MyPagerAdapter : PagerAdapter() {
        override fun getItem(position: Int) = when(position) {
            0 -> Fragment0()
            1 -> Fragment1()
        }
    
        override fun getCount() = 2
    }
    

    getCount() 只返回2,但显示一条错误消息 'when' expression must be exhaustive, add necessary 'else' branch else 但写这样的代码真的很难看:

        when(position) {
            0 -> Fragment0()
            1 -> Fragment1()
            else -> Fragment()    // Impossible to get here
        }
    

    有没有更好的办法解决这个问题?谢谢。

    4 回复  |  直到 6 年前
        1
  •  8
  •   Stanislav Mukhametshin    6 年前

    1) 如果你不可能找到你能找到的其他分支

    抛出IllegalStateException(“片段$position不正确”)

    您的代码可以随时更改。它将帮助您更好地理解您发送的值不正确。

    2) 另外,如果只有两个case,那么就可以使用if(…){}else{}语句

    3) 可以使用枚举值来不使用else分支(而不是位置)。

        2
  •  4
  •   Miha_x64    6 年前

    position in 0 until 1 你必须加上 else 希望它永远不会被称为:

    else -> throw AssertionError()
    
        3
  •  3
  •   Emre Eran    6 年前

    如果您想以正确的方式执行,请在else分支中抛出一个异常。请记住,将来可能会有其他人维护您的代码库,并在其他情况下尝试使用此适配器。

    我知道现在这似乎不太可能,也不需要额外的努力,但习惯这些小事对我来说很重要。

        4
  •  1
  •   Eric Martori    6 年前

    正如其他人所说,如果您确定不会有更多的元素,您可以将else分支更改为 throw IllegalStateException("Fragment $position is not correct")

    如果您完全确定不会有更多选项,并且希望维护简洁声明,另一个选项是使用if表达式:

    fun getItem(position: Int) = if(position == 0) Fragment0() else Fragment1()
    

    这种方法的问题是,如果适配器上有新元素,那么它就不可扩展。另外,如果传递了一个无效的位置,它将返回一个Fragment1()实例,而不是崩溃。 取决于你的需要,这可能是一个好的选择或不是。

        5
  •  1
  •   Scre    4 年前

    position 接受任何值,并用模调整值。那样的话你需要 else 只为捕捉实际丢失条目的情况:

    class MyPagerAdapter : PagerAdapter() {
        override fun getItem(position: Int) = when(position % getCount()) {
            0 -> Fragment0()
            1 -> Fragment1()
            else -> throw IllegalStateException("Someone forgot to add enough fragment cases to 'when' clause!")
        }
    
        override fun getCount() = 2
    }