How to cast Lambda to Unit

Have such kind of a code:

someData?.run {
// consuming this data
} ?: reportNoData()

fun reportNoData() {
// report no data
}

Now trying to replace function with lambda, like this

someData?.run {
// consuming this data
} ?: {
// report no data
}

But it won’t compile, complaining on the last block with:
Type mismatch: inferred type is () → Unit but Unit was expected

Hmm, weird, ok, changing to

someData?.run {
// consuming this data
} ?: {
// report no data
}()

makes it compile and run.
But the syntax is not obvious. Is it possible to write it simpler?

Hmm, imho regarding your third code snippet, the syntax is obvious

Because { } is an object of () → (Unit) type, and you don’t use it in an assignment or expression, but in an invocation, you must invoke the lambda object.

why you just don’t if (someData!=null) {} else {}. Looks more clean.

3 Likes

Thanks for reply!

Because I want get it in Kotlin-style syntax, without manual null compare and branching.
Basically want to find minimum possible code :wink:

Well, less verbose doesn’t always mean more clean or readable.

I stopped using run and apply in my code because modifying the meaning of this turned out to be a bad idea in some cases, because it increases ambiguity.

Example: something.run { x=y } — when i write the code I knew that x is from something and y is from the parent object or the method’s scope… but after a while this code gets confusing and way less readable, resulting in bugs that are not easy to detect during a quick read.

I almost always use something?.let{something → } and if(…)… even if I write more code, it’s more readable.

I also use run, apply, but only when it’s highly needed

Good point. Kotlin gives so many possibilities (except ternary operator), which can lead to unreadable code. Hard to find a balance :slight_smile: That should come with experience.

You most likely wanted to do this:

someData?.run {
	// consuming this data
} ?: run {
	// report no data
}

but I think that a simple if/else with smart-casting would be better in this case :wink:

1 Like

Exactly what I was looking for! :clap: