Kotlin vs Swift — Enumeration

Tonny
6 min readFeb 5, 2021

I love programming in Android and iOS platforms with Kotlin and Swift, I will demonstrate the difference and similarity of enumeration using code in this post, it is part of this language comparison series.

Definition of Enumeration

Kotlin

In Kotlin, each enum constant is an object.

enum class Direction { 
NORTH, SOUTH, WEST, EAST
}

Swift

But in Swift, an enumeration defines a common type for a group of related values and enables you to work with those values in a type-safe way within your code. Each enum case is a value.

enum Direction {
case north
case south
case west
case east
}

enum Direction {
case north, south, west, east
}

Represent values

Kotlin

In Kotlin, each enum is an instance of the enum class. Int or String values can be represented by parameters of the primary constructor of the enum class.

enum class Color(val rgb: Int) {
RED(0xFF0000),
GREEN(0x00FF00),
BLUE(0x0000FF)
}

enum class Color(val rgb: String) {
RED("0xFF0000"),
GREEN("0x00FF00"),
BLUE("0x0000FF")
}

val color = Color.RED
val rgb = color.rgb

Swift

But in Swift, if a value (known as a raw value) is provided for each enumeration case, the value can be a string, a character, or a value of any integer or floating-point type. The value is represented by raw value rather than an extra parameter in Kotlin.

enum Color : Int {
case red = 0xFF0000
case gree = 0x00FF00
case blue = 0x0000FF
}

enum Color : String {
case red = "0xFF0000"
case gree = "0x00FF00"
case blue = "0x0000FF"
}

val color = Color.red
val rgb = color.rawValue

Anonymous class

Kotlin

In Kotlin, enum constants can also declare their anonymous classes with their corresponding methods, as well as overriding base methods. The anonymous class appended on the enum instance is a great place with the ability to extend the enum instance.

enum class ProtocolState {
WAITING {
override fun signal() = TALKING
},

TALKING {
override fun signal() = WAITING
};

abstract fun signal(): ProtocolState
}

val state = ProtocolState.WAITING.signal()

Swift

But in Swift, enum case is an atom, but we can implement a similar function in enum type using switch case.

enum ProtocolState {
case waiting, talking

func signal() -> ProtocolState {
switch self {
case .waiting:
return .talking
case .talking:
return .waiting
}
}
}

let state = ProtocolState.waiting.signal()

Implementing Interfaces

Kotlin

In Kotlin, an enum class may implement an interface (but not derive from a class), providing either a single interface members implementation for all of the entries.

enum class IntArithmetics : BinaryOperator<Int> {
PLUS,
TIMES;

override fun apply(t: Int, u: Int) =
when (this) {
PLUS -> {
t + u
}
TIMES -> {
t * u
}
}
}

IntArithmetics.PLUS.apply(13, 31)

or separate ones for each entry within its anonymous class.

enum class IntArithmetics : BinaryOperator<Int> {
PLUS {
override fun apply(t: Int, u: Int): Int = t + u
},
TIMES {
override fun apply(t: Int, u: Int): Int = t * u
};
}

Swift

But in Swift, there is no anonymous class like Kotlin, but enum type is good enough to implement any protocol using switch case. If you don’t like the long-winded switch like me, unfortunately, there is no better way to do it.

enum IntArithmetics: IntBinaryOperator {
case plus, times

func apply(_ t: Int, _ u: Int) -> Int {
switch self {
case .plus:
return t + u
case .times:
return t * u
}
}
}

IntArithmetics.plus.apply(13, 31)
IntArithmetics.times.apply(13, 31)

Working with Enum Constants

Kotlin

In Kotlin, enum classes have synthetic methods allowing valueOf(value:) to list the defined enum constants and values() to get an enum constant by its name.

enum class Direction {
NORTH, SOUTH, WEST, EAST
}

Direction.valueOf(value="NORTH") //Direction.NORTH
Direction.values() //Array<Direction>

Direction.NORTH.name

And since Kotlin 1.1, it’s possible to access the constants in an enum class in a generic way.

enumValueOf<Direction>(name="NORTH") //Direction.NORTH
enumValues<Direction>() //Array<Direction>

Those implicit and auto-generated api are very handy if you read the official document carefully.

Swift

But in Swift, enum can be constructed only if the enum derives from a class. the derivation provides both raw value and accessible initializer EnumType(rawValue:). Enum cases can be iterated with the help of CaseIterable protocol. Comparing with Kotlin, Swift need to be more explicit.

enum Direction : String, CaseIterable {
case north, south, west, east
}

Direction(rawValue: "north") //Direction.north
Direction.allCases

Direction.north.rawValue

Superclass

Kotlin

In Kotlin, Enum class is the common base class of all enum classes.

abstract class Enum<E : Enum<E>> : Comparable<E>

Swift

But in Swift, there is no common base class for enum type.

Shorter dot syntax

Kotlin

In Kotlin, there is no shorter dot syntax when using enum.

Swift

But in Swift, the type of directionToHead is inferred when it’s initialized with one of the possible values of Direction. Once directionToHead is declared as a Direction, you can set it to a different Direction value using shorter dot syntax.

var directionToHead = Direction.west
directionToHead = .east

Implicitly Assigned Raw Values

Kotlin

In Kotlin, if enum class has one primary constructor, all enum instance have to call it explicitly.

enum class Color(val rgb: Int) {
RED(0xFF0000),
GREEN(0x00FF00),
BLUE(0x0000FF)
}

Swift

But in Swift, when you’re working with enumerations that store integer or string raw values, you don’t have to explicitly assign a raw value for each case. When you don’t, Swift automatically assigns the values for you.

enum Planet: Int {
case mercury = 1, venus, earth
}

In the example above, Planet.mercury has an explicit raw value of 1, Planet.venus has an implicit raw value of 2, and so on.

Associated Values

Kotlin

In Kotlin, enum instances have the same parameters come from the primary constructor, it restricts all instances need to be in the same structure. But in some sense, instances may have different structures with others. We have to ask the sealed class for help.

sealed class Barcodedata class Upc(val number1: Int, val number2: Int, val number3: Int, val number4: Int) : Barcode()data class QrCode(val code: String) : Barcode()

Swift

But in Swift, enumeration cases can specify associated values of any type to be stored along with each different case value.

enum Barcode {
case upc(Int, Int, Int, Int)
case qrCode(String)
}

Recursive Enumerations

A recursive enumeration is an enumeration that has another instance of the enumeration as the associated value for one or more of the enumeration cases.

Kotlin

In Kotlin, we already know when the set of value is restricted like enum instance and they have its own structure, we can use sealed class rather than enum class.

sealed class ArithmeticExpressiondata class Number(val value: Int) : ArithmeticExpression()data class Addition(val exp1: ArithmeticExpression, val exp2: ArithmeticExpression) : ArithmeticExpression()data class Multiplication(val exp1: ArithmeticExpression, val exp2: ArithmeticExpression) : ArithmeticExpression()val sum = Addition(Number(5), Number(4))
val product = Multiplication(sum, Number(2))

Swift

But in Swift, enum supports this feature in language level.

indirect enum ArithmeticExpression {
case number(Int)
case addition(ArithmeticExpression, ArithmeticExpression)
case multiplication(ArithmeticExpression, ArithmeticExpression)
}

Summary of Enumeration

Kotlin

  • enum case is an instance (an object) of enum class
  • represents value using primary constructor
  • enum instance can be extended using anonymous classes👏
  • Kotlin compiler generates synthetic methods implicitly
  • enum = enum class + sealed class

Swift

  • enum case is a value of enum type👏
  • represents value using deriving from the type of value
  • enum case is an atom, extend them in parent (enum type) using switch
  • please explicitly in Swift👏
  • enum = enums, even associating value and recursion👏

I give 👏 to some enum features of Kotlin and Swift personally, and I love both of them, especially when you realise the genius idea of language design from different aspect. If you like this post, please share and stay awesome.

--

--