Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Difference between with and run in Kotlin

Tags:

kotlin

Do with and run have the same functionality with only different syntax, or is there any major differences between with and run?

Which is the proper way?

adapter.run {     notifyDataSetChanged()     if (activityDetails.isEmpty())         emptyText.visibility = View.VISIBLE     else         emptyText.visibility = View.GONE }   with(adapter){    notifyDataSetChanged()    if (activityDetails.isEmpty())        emptyText.visibility = View.VISIBLE    else         emptyText.visibility = View.GONE } 
like image 699
Sai Avatar asked Jul 21 '16 10:07

Sai


People also ask

What is the difference between with and apply in Kotlin?

There're two differences: apply accepts an instance as the receiver while with requires an instance to be passed as an argument. In both cases the instance will become this within a block. apply returns the receiver and with returns a result of the last expression within its block.

What is Kotlin run?

The Android Kotlin compiler produces Java 8 bytecode by default (which runs in any later JVM), but lets the programmer choose to target Java 9 up to 18, for optimization, or allows for more features; has bidirectional record class interoperability support for JVM, introduced in Java 16, considered stable as of Kotlin ...

What does .apply do in Kotlin?

Kotlin :: apply In Kotlin, apply is an extension function on a particular type and sets its scope to object on which apply is invoked. Apply runs on the object reference into the expression and also returns the object reference on completion.


Video Answer


1 Answers

They have only syntactic difference, run is an extension function while with is not. Here are the definitions (in kotlin-sdlib:1.0.3):

public inline fun <T, R> T.run(block: T.() -> R): R = block() // equivalent to this.block()  public inline fun <T, R> with(receiver: T, block: T.() -> R): R = receiver.block() 

Since run is an extension function, it has one more implicit argument of type T, so the argument types are the same. The bodies of the functions are also effectively the same.

Their performance should also be equivalent since both are inline functions: the resulting bytecode should only contain the inlined block body.


The differences in the functions usage are all caused by the fact that run is an extension.

First, run is suitable for calls chaining:

foo.run { bar }.run { baz } 

Second, and more important, if a declared variable type has run function with the same signature, it will be called instead of the extension. And run can be shadowed by another extension. This is how extensions are resolved. Example:

class MyClass {      fun <R> run(blockIgnored: MyClass.() -> R): Nothing = throw RuntimeException() }  "abcdefg".run { println("x") } // prints "x" MyClass().run { println("x") } // throws RuntimeException (MyClass() as Any).run { println("x") } // prints "x" 
like image 100
hotkey Avatar answered Sep 19 '22 22:09

hotkey