kotlinenumskotlin-when

Kotlin: Omitting enum name when its unambiguous


With Swift enums you can omit the name of the enum in cases where only a value of that type can be used.

So when given the enum (Swift/Kotlin)

enum (class) CompassPoint {
  case north
  case south
  case east
  case west
}

Swift only needs the enums name when creating a new variable:

// type unclear, enum name needed
var directionToHead = CompassPoint.west

// type clear, enum name can be dropped
directionToHead = .east

// type clear, enum name can be dropped
switch directionToHead {
case .north:
  print("Lots of planets have a north")
case .south:
  print("Watch out for penguins")
case .east:
  print("Where the sun rises")
case .west:
  print("Where the skies are blue")
}

While in Kotlin, for the same situation you'd have to write

// type unclear, enum name needed
var directionToHead = CompassPoint.west

// type clear, enum name still needed
directionToHead = CompassPoint.east

// each case needs the enum name
when(directionToHead) {
  CompassPoint.north -> println("Lots of planets have a north")
  CompassPoint.south -> println("Watch out for penguins")
  CompassPoint.east -> println("Where the sun rises")
  CompassPoint.west -> println("Where the skies are blue")
}

Is there a reason for this, and/or are there situations in Kotlin where just .north or north can be used?

Edit: It seems importing the enum 'fixes' this and is necessary even when the enum is defined in the same file as it is used.

While this helped practically, I still don't understand why the import is needed.


Solution

  • Edit: It seems importing the enum 'fixes' this and is necessary even when the enum is defined in the same file as it is used.

    While this helped practically, I still don't understand why the import is needed.

    Simply because it isn't treated specially. import CompassPoint.* lets you write just <name> for anything you'd write as CompassPoint.<name> without it (if the name doesn't conflict with anything). If you happen to be in the file where CompassName is defined, it works exactly the same.

    You can refer to the values as north etc. without imports inside the enum definition, exactly like you can refer to an object's members inside this object:

    object Obj {
        val v = 0
        val v1 = v
    }
    
    val v2 = Obj.v
    

    or

    import Obj.* // or import Obj.v
    val v2 = v