2

I wrote this method to apply a void function to a value and return the value.

public inline fun <T> T.apply(f: (T) -> Unit): T {
    f(this)
    return this
}

This is useful in reducing something like this:

return values.map {
    var other = it.toOther()
    doStuff(other)
    return other
}

To something like this:

return values.map { it.toOther().apply({ doStuff(it) }) }

Is there a language feature or method like this already build in to Kotlin?

Michael Pardo
  • 2,590
  • 3
  • 24
  • 33
  • Just for my education, the point of `doStuff` here is to evaluate it for its side-effects, a bit like the `peek` method in Java 8 streams? – Greg Kopff Feb 13 '15 at 23:29
  • Yes, I think it's similar to `peek`, but applied to an object instead of a stream. It also reminds me of RxJava's `doOnNext()`, but again, applied to an object instead of a stream. And the point of `doStuff` is really up to the user, but in my case it's to add to `other` a cache. – Michael Pardo Feb 16 '15 at 14:51
  • Related issue https://youtrack.jetbrains.com/issue/KT-6903. Feel free to vote or star to get updates. – bashor Mar 04 '15 at 11:35
  • the `apply` function is now part of the Kotlin standard library. See answer below for details. – Jayson Minard Jan 02 '16 at 01:55

2 Answers2

4

Apply is in the Kotlin standard library: See the docs here: https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/apply.html

Its method signature:

inline fun <T> T.apply(f: T.() -> Unit): T (source)

Calls the specified function f with this value as its receiver and returns this value.

Jayson Minard
  • 84,842
  • 38
  • 184
  • 227
1

I ran into the same problem. My solution is basicly the same as yours with a small refinement:

inline fun <T> T.apply(f: T.() -> Any): T {
    this.f()
    return this
}

Note, that f is an extension function. This way you can invoke methods on your object using the implicit this reference. Here's an example taken from a libGDX project of mine:

val sprite : Sprite = atlas.createSprite("foo") apply {
    setSize(SIZE, SIZE)
    setOrigin(SIZE / 2, SIZE / 2)
}

Of course you could also call doStuff(this).

Kirill Rakhman
  • 42,195
  • 18
  • 124
  • 148