https://kotlinlang.org logo
Title
t

Thomas Hormes

05/25/2023, 6:09 AM
I have code like the following:
enum class Test {
    A, B, C
}

fun enumTest(variant: Test) {
    if(variant != Test.A) {
        val temp = when(variant) {
            Test.A -> "I am useless :("
            Test.B -> "Foo"
            Test.C -> "Bar"
        }
        
        println(temp)
        // Do things that depend on variant not being A
    }
}
IntelliJ (correctly) tells me that the branch
Test.A
is unreachable. When removing this branch of the
when
statement however, I get a compiler error, stating the
when
is not exhaustive. Am I just doing things not idiomatically or is this an area where the Kotlin compiler could still be improved?
a

Adam S

05/25/2023, 6:57 AM
it would be nice if the smart cast worked, but given the current situation I think the idiomatic quick-and-easy fix would be to use
null
to exclude
Test.A
enum class Test {
    A, B, C
}

fun enumTest(variant: Test) {
    val temp = when (variant) {
        Test.A -> null
        Test.B -> "Foo"
        Test.C -> "Bar"
    }

    if (temp != null) {
        println(temp)
        // Do things that depend on variant not being A}
    }
}
And if you wanted to make things more robust (or, arguably, complicated), you could use multiple sealed types to differentiate the variants based on inclusion rather than exclusion.
sealed interface VariantX

sealed interface Test {
  object A : Test
  object B : Test, VariantX
  object C : Test, VariantX
}

fun enumTest(variant: Test) {
  if (variant is VariantX) {
    val temp = when (variant) {
      Test.B -> "Foo"
      Test.C -> "Bar"
    }
    println(temp)
    // Do things that depend on variant being VariantX}
  }
}
s

Stephan Schröder

05/25/2023, 1:40 PM
my code golfing attempt
val x: Text = Test.A
val valuePerVeriant = mapOf {
    Test.B to "foo",
    Test.C to "bar",
}
valuePerVeriant[x]?.let {
    println(it)
}