Assuming I have a function example()
that has a parameter param: Int?
. I would like to call it so that the argument can be passed with certain conditionals.
To try to explain better, let's define the example()
function:
fun example(prev: Int, param: Int?) = doSomething(prev, param)
So assuming that under certain conditions, the value passed as an argument can be null
or any other value. Naturally, I would do something like this:
val param = if (x() > 100) null
else if (x() < 0) 123
else 456
example(123, param)
Another way to get this to work would be inline val
like this:
example(123, if (x() > 100) null
else if (x() < 0) 123
else 456)
The problem is that I have a larger conditional in my real code and it ends up being very "visually accumulated". Both examples works, but I wanted to not using else
or when
under these conditions. It would be something like:
example(123, run {
if (x() > 100)
return null
if (x() < 0)
return 123
return 456
})
However, the code above does not work as expected. The return
points actually cause the entire flow of the function to return, and are not meant to return as the argument itself.
What I expect, in reality, would be something like the function below:
fun generateExampleArgument(): Int? {
if (x() > 100)
return null
if (x() < 0)
return 123
return 456
}
// Then:
example(123, generateExampleArgument())
CodePudding user response:
In regard of readability and quote "... larger conditionals ..." the when clause is better than the if ... else if ... one:
example(
123,
when {
x() > 100 -> null
x() < 0 -> 123
else -> 456
}
)
Another possibility is to use a function to pre-calculate the result for the second argument of example() or a lambda function, which moves the execution of that function into example() itself:
fun example(prev: Int, fn: (Int) -> Int?, x: Int) = doSomething(prev, fn(x))
val myLambda = { x: Int ->
when {
x > 100 -> null
x < 0 -> 123
else -> 456
}
}
example(120, myLambda, 111)
CodePudding user response:
After many attempts, I finally figured out how to solve it. My problem is that when using just return
it actually instructs the return to the "larger function context", not on the argument itself, as expected.
The solution is to use run
with return@run
:
example(123, run {
if (x() > 100)
return@run null
if (x() < 0)
return@run 123
456
})