Light Yagami
Light Yagami

Reputation: 1043

Kotlin: How to define a variable whose type depends on the input?

I have a function in Kotlin which takes a particular string as input. Depending on the input, I want to create a variable of a specific type and do some computations on it.

For example,

fun compute(input: String): Any{
    if(input=="2d"){
        var point: Point2D;// Points2D - x: int, y: int
        //initilize and do some computations
        return point.findDistanceFromOrigin()
    }else if(input=="2d-1"){
        var point: Point2DWithP1AsOrigin;// Point2DWithP1AsOrigin - x: int, y: int
        //initilize and do some computations
        return point.findDistanceFromOrigin()
    }else if(input=="2d-2"){
        var point: Point2DWithP2AsOrigin;
        //initilize and do some computations
        return point.findDistanceFromOrigin()
    }
    .
    .
    .
}

You can see in the above example, I want to initilize the type of point depending on the input and do computation and return.

All the if-else conditions have the same code except for the definition of the variable. How can I put all this in a single block with something like this:

var point: if(input=="2d) Point2D::class else if(input=="2d-1") Point2DWithP1AsOrigin::class.....

How can I do that?

Upvotes: 0

Views: 109

Answers (2)

Nikolai  Shevchenko
Nikolai Shevchenko

Reputation: 7521

You can store constructor references and then invoke required one

fun main() {
    val constructors = mapOf(
        "2d"   to ::Point2D,
        "2d-1" to ::Point2DWithP1AsOrigin,
        "2d-2" to ::Point2DWithP2AsOrigin,
    )

    val type = "2d-2"
    val constructor = constructors[type] ?: throw IllegalArgumentException("$type not supported")
    val point = constructor()

    println(point::class)
}

Output

class Point2DWithP2AsOrigin

Upvotes: 1

Ivo
Ivo

Reputation: 23357

You could do something like this

fun compute(input: String): Any{
    val point: MyPoint = when(input) {
        "2d" -> Point2D()
        "2d-1" -> Point2DWithP1AsOrigin()
        "2d-2" -> Point2DWithP2AsOrigin()
        else -> Point2D() //fallback is necessary
    }
    //initilize and do some computations
    return point.findDistanceFromOrigin()
}

But then it's essential that all those classes share the same interface. Because they need to have the same methods in order to do the same operations on them. For example like this:

class Point2D : MyPoint {
    override fun findDistanceFromOrigin() = 5
}

class Point2DWithP1AsOrigin : MyPoint{
    override fun findDistanceFromOrigin() = 6
}

class Point2DWithP2AsOrigin : MyPoint{
    override fun findDistanceFromOrigin() = 7
}

interface MyPoint {
    fun findDistanceFromOrigin() : Int
}

Upvotes: 2

Related Questions