I have a code that logically can have only 3 values. But the when assignment is on a Int variable type. What can i do, if i don't have a RecyclerView.ViewHolder object to return if non of the "cases" in the when expression won't happen (a situation that can't be). I can solve it with "ugly" solution that if 'else' so return of one of the RecyclerView.ViewHolder that i'm returning in the existing cases, but i want to know if there is more elegant way to deal with this situation. I have the following code:
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
return when (viewType)
{
DataTypesEnum.COUNTRY_ITEM.ordinal -> CountryDataItem.onCreateViewHolder(parent)
DataTypesEnum.LEAGUE_ITEM.ordinal -> LeagueDataItem.onCreateViewHolder(parent)
DataTypesEnum.GAME_ITEM.ordinal -> GameDataItem.onCreateViewHolder(parent)
}
}
the compiler says that :
when' expression must be exhaustive, add necessary 'else' branch
[I] want to know if there is more elegant way to deal with this situation.
If you're absolutely sure that the viewType
index will be in the right range, you can get the enum
from the list. Then you'll just need to switch on that enum.
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
return when (DataTypesEnum.values()[viewType])
{
DataTypesEnum.COUNTRY_ITEM -> CountryDataItem.onCreateViewHolder(parent)
DataTypesEnum.LEAGUE_ITEM -> LeagueDataItem.onCreateViewHolder(parent)
DataTypesEnum.GAME_ITEM -> GameDataItem.onCreateViewHolder(parent)
}
}
I agree with J. Hegg's response in that you should be cautious!
Update 2020-11-23 with further context:
I'm just very curious how the line (DataTypesEnum.values()[viewType]) makes all the when return statement to be exhaustive and prevent from the compiler to complain on exhaustive issue?
In your initial example you switch on an Int
type.
when (viewType) {
// ...
}
Therefore, to make the complier happy with viewTypes
, you either need to cover all possible values of Int
, or include an else
statement in the when
block.
My suggestion maps the Int
type to the corresponding DataTypesEnum
before switching on it. That way, the when
block only needs all DataTypesEnum
options accounted for to be exhaustive.
DataTypesEnum.values()
returns an Array<DataTypesEnum>
of all of the DataTypesEnum
in order which is very similar to using the #ordinal
values in your solution.
The next step is to get the value from the array, which I use the index access operator [ ]
.
DataTypesEnum.values()[viewType]
// is the same as
DataTypesEnum.values().get(viewType)
That should do the trick!
If you're not sure if viewType
will fall into the right range, you might want to check the value so you don't hit an IndexOutOfBoundsException
.
Hopefully that answers your question!