I've run into an issue compiling an expression. I...
# general-advice
a
I've run into an issue compiling an expression. I understand why it happened, and how to work around it. I just wonder if there's a better workaround. Given this class:
Copy code
class BusinessLogic(
    val getMessage: () -> String
)
I want to build a factory method that would let me override
getMessage
with some static String.
Copy code
fun createBusinessLogic(messageOverride: String? = null): BusinessLogic
I initially came up with this:
Copy code
fun createBusinessLogic(
    messageOverride: String? = null
) = BusinessLogic(
    getMessage = if (messageOverride != null) {
        { messageOverride }
    } else {
        val random = Random(1337)
        { "Message ${random.nextInt()}" }
    }
)
Which fails to compile, because the compiler thinks the
() -> String
I'm trying to return is an argument to the
Random
constructor. My workaround was to assign the lambda to a
val
, and then return that on the next line.
Copy code
fun createBusinessLogic(
    messageOverride: String? = null
) = BusinessLogic(
    getMessage = if (messageOverride != null) {
        { messageOverride }
    } else {
        val random = Random(1337)
        val supplier = {
            "Message ${random.nextInt()}"
        }
        supplier
    }
)
But it's weird! And ugly! I feel like there should be a better way to do this, without resorting to something drastic like:
Copy code
fun createBusinessLogic(
    messageOverride: String? = null
) = if (messageOverride != null) {
    BusinessLogic { messageOverride }
} else {
    val random = Random(1337)
    BusinessLogic { "Message ${random.nextInt()}"}
}
Which won't really fly in my real app, because the real-life
BusinessLogic
has several more arguments that would be duplicated.
e
it's annoying but I think
Copy code
val random = Random(1337)
({ "Messagee ${random.nextInt()}" })
may be the easiest workaround
there are other options as well, such as
Copy code
Random(1337).let { random ->
    { "Message ${random.nextInt()}" }
}
Copy code
val random = Random(1337)
fun() = "Message ${random.nextInt()}"
and of course,
Copy code
val random = Random(1337);
{ "Message ${random.nextInt()}" }
but I think
;
breaks Kotlin style more than the other options
a
Oh, I think this is a prettier workaround, thanks!
Copy code
({ "Message ${random.nextInt()}" })
I also completely forgot that
;
was an option to break up the clauses, and the editor doesn't even complain about it being redundant. But still, nice to avoid using
;
.