Search code examples
kotlinkotlin-extensionextension-function

Kotlin scope functions with vs extension run


From what I've learned, it seems like extension function T.run and with have kind of the same purpose of creating the possibility to group multiple calls on the same object, returning lambda's last object as its result.

T.run() has the advantage of applying check for nullability before using it. (as this article points it out)

What are the advantages of using with? or better said: What stops me from always using T.run() instead? Thanks


Solution

  • This is the case for many scope functions, you can't always tell which one is "correct" to be used, it's often the developer's choice actually. As for with and run, the only difference is how the receiver of the scope function comes into play:

    On the one hand, the receiver is passed as an argument to with:

    val s: String = with(StringBuilder("init")) {
        append("some").append("thing")
        println("current value: $this")
        toString()
    }
    

    On the other hand, run directly gets called on the receiver (extension function):

    val s: String = StringBuilder("init").run {
        append("some").append("thing")
        println("current value: $this")
        toString()
    } 
    

    run has the advantage of nullability-handling since the safe operator can be applied:

    val s: String = nullableSB?.run {
       //...
    } ?: "handle null case"
    

    I haven’t seen many usages of run whereas with is more commonly used I think.