Greg Kopff
Greg Kopff

Reputation: 16545

Kotlin equivalent of Optional.map and a method reference

The Java

Consider the following Java:

private void example() {
  Optional<String> foo = ...
  Optional<String> bar = 
      foo.map(this::transform1)
          .map(this::transform2)
}

private String transform1(String s) {
  return s + "!";
}

private String transform2(String s) {
  return "@" + s;
}

Note that the transform methods accept non-Optional values.

Question

Does Kotlin have a built-in mechanism to achieve the same thing when using its nullable/non-nullabe types?

The first attempt

I managed to achieve this effect with the following:

fun <A, B> nullMap(a: A?, mapper: (a: A) -> B?): B? =
  if (a != null) mapper.invoke(a) else null

fun example() {
  val foo: String? = "Space cookies"
  val bar1: String? = nullMap(foo, Example::transform1)
  val bar2: String? = nullMap(bar1, Example::transform2)
}

fun transform(s: String) = s + "!"
fun transform2(s: String) = "@" + s

(Again, we note that for the transform methods, s is a non-nullable String.)

So, my question stated another way is: Does a nullMap equivalent already exist in Kotlin's standard library? And/or: is there a different standard way of doing this?

Finally, can the visually cleaner chaining approach be achieved in Kotlin, rather than either separate assignments (above) or nested function calls? For a moment I considered that you could add nullMap as an extension method on Any, but sometimes the receiver you're trying to invoke a method on is null (so that won't work).

Upvotes: 10

Views: 9562

Answers (1)

glee8e
glee8e

Reputation: 6419

We use safe call operator:

val foo: Foo? = ...
foo?.toA()?.toB()

Or

foo?.let(this::transform1)?.let(this::transform2)

Kotlin emphasis on null safety. There is an entire chapter in its manual describing related technics.

Upvotes: 19

Related Questions