Quantcast
Viewing latest article 1
Browse Latest Browse All 5

Answer by cactustictacs for starts with inside switch statement Kotlin

You can't really do this and avoid the repetition, because when you provide an argument in when (something) the something is an expression that produces a value, which is fixed before the matching starts. And then your branch expressions are compared to that fixed value, trying to find an equals match (or a few other special cases, like is or in)

The closest you can get is what sirjoga is going for, where you don't provide an argument to when, so the branch conditions are just simple boolean expressions. So instead of each condition being a value trying to match that something value, you make a function call that produces a true or false value, and the when block uses the first one that matches true.


If you really need to avoid the repetition while keeping it looking like a standard when matcher, you could do something like this:

fun <T, R> when2(    predicate: (T) -> Boolean,    matchers: Map<T, () -> R>,    default: () -> R) : R{    val match = matchers.entries.firstOrNull { predicate(it.key) }?.value ?: default    return match.invoke()}fun main() {    val thing = "this is a sentence"    when2({ thing.startsWith(it) },         mapOf("this" to { println("Starts with this") },"that" to { println("Starts with that") }        ), default = { println("uh oh") }       )}

But then you're creating a Map each time it's called, instead of getting compiled neatly into some basic conditional code. You could create a stateful object (so you pass this all into the function call, but it stores it and returns an object that lets you do checks):

fun <T, R> whenMaker(    matchers: Map<T, () -> R>,    default: () -> R) : ((T) -> Boolean) -> R{    return { predicate ->        val match = matchers.entries.firstOrNull { predicate(it.key) }?.value ?: default        match.invoke()    }}fun main() {        val match = whenMaker(        mapOf("this" to { println("Starts with this") },"that" to { println("Starts with that") }        ), default = { println("uh oh") }       )    match { "this is a sentence".startsWith(it) }    match { "that is a sentence".startsWith(it) }    match { "them is a sentence".startsWith(it) }}

But now you're separating the definition of your when structure from where it's actually used - especially as ideally, you wouldn't be creating that match object inside your function since that could happen repeatedly. But, depending on what you're doing and how much it matters, something like this could be useful! E.g. a convenience class that defines the match object in a top-level variable, directly above the function that makes use of it might not be so bad.


Viewing latest article 1
Browse Latest Browse All 5

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>