I have enum in swift
enum Type {
case bool(Bool)
case int(Int)
case array([String])
}
Dont understand how i can convert this to kotlin code, i did like this:
enum class AnswerSheetType {
BOOL,
INT,
ARRAY
}
But how i can pass variable to enum type. For example then i want create method which will be return type with variable, like this(swift code):
func marks(for id: String) -> Type {
let answer = answers?[id]
if let boolAnswer = answer as? Bool {
return .bool(boolAnswer)
}
if let intAnswer = answer as? Int {
return .int(intAnswer)
}
if let arrayAnswer = answer as? [String] {
return .array(arrayAnswer)
}
}
CodePudding user response:
You can use a sealed interface/class to represent this.
sealed interface Type {
data class BoolType(val value: Bool) : Type
data class IntType(val value: Int) : Type
data class ArrayType(val value: Array<String>) : Type
// if you have a case that doesn't have any associated values, just use an object
// object CaseWithoutAssociatedValues: Type
}
Usage:
// let someType: Type = .bool(true)
val someType: Type = Type.BoolType(true)
// just like how you can use a switch on a Swift enum, you can use a when like this too:
// This when is also exhaustive, if you specify all the implementers of Type
when (someType) {
is Type.BoolType -> println("Bool value: ${someType.value}")
is Type.IntType -> println("Int value: ${someType.value}")
is Type.ArrayType -> println("Array value: ${someType.value}")
}
Notice that in each of the branches, you can access someType.value
, because of the smart-cast. This is unlike in Swift, where you would do pattern matching to get the associated values out.
CodePudding user response:
As I was writing my answer Sweeper already answered with almost the identical solution. I wanted to add to that, that your marks
function could then be written as this:
fun marks(id: String) : Type? {
when (val answer = answers?.get(id)) {
is Boolean -> return Type.BoolType(answer)
is Int -> return Type.IntType(answer)
is Array<*> -> if (answer.isArrayOf<String>()) return Type.ArrayType(answer as Array<String>)
}
return null
}
The Array
case is a bit ugly but that is because checking on is Array<String>
is not possible. The IDE will also still complain about having an unchecked cast but it should work. I don't know if there's a nicer way to handle this.