'when' expression must be exhaustive error when using adapters

'when' expression must be exhaustive error when using adapters

I would like to do something like this:

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

    override fun getCount() = 2

I am sure that the adapter contains only 2 items, so getCount() simply returns 2. But it shows an error message said that 'when' expression must be exhaustive, add necessary 'else' branch. I understand that I can add an else to solve it, but it's really ugly to write code like:

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

Is there any better way to solve it? Thanks.

1) If it impossible to get at else branch than you can

throw IllegalStateException("Fragment $position is not correct")

Your code can be changed at any time. And it will help you to better understand that you send not correct values.

2) Also if you have only two cases than you can use if (..) {} else {} statement

3) You can use Enum values to do not have else branch (instead of position).

There's no way for compiler to figure out that position is in 0 until 1. You must add else branch and hope it won't ever be called:

else -> throw AssertionError()

If you want to do it the proper way, throw an exception in the else branch. Keep in mind that may be in the future someone else will be maintaining your code base and will try to use this adapter in another situation.

I know this seems unlikely right now and unnecessary extra effort, but getting used to these small things is important IMHO.

As others have said if you are sure there won't be more elements you can change the else branch to throw IllegalStateException("Fragment $position is not correct"). Trying to use and enum or sealed class to make the when case exaustive will just move this problem to the function you use to tranform the Int to the new restricted type.

Another option if you are completly sure there won't be any more options and want to maintain a concise declaration is to use an if expression:

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

The problem with this approach is that is not extensible if you end up having new elements on the adapter. Also if an invalid position is passed, instead of crashing it will return a Fragment1() instance. Depending on your needs could be a good option or not.