Using 'with(...)' Function with Multiple Receivers?


#1

Are there any plans to have Kotlin’s built in ‘with’ function take in multiple receivers? I find that it could be useful in several scenarios.

For instance, the following code:

val args = Bundle()
args.putString(SomeActivity.stringKey, “String”)
args.putInt(SomeActivity.intKey, 12345)
args.putChar(SomeActivity.charKey, ‘c’)

Could possibly be made into:

with(args, activity) {
putString(stringKey, “String”)
putInt(intKey, 12345)
putChar(charKey, ‘c’)
}


#2

No, there are no such plans.

You can nest with functions to add implicit receivers to scope, like:

with(args) {
    with(activity) {
         putString(stringKey, "String")
    }
}

However I would not recommend abusing with function like this, as it makes unclear which property/function refers to which implicit receiver.


#3

Very recently a friend asked me for this same thing.

Does this suit your needs?

inline fun <T> with(vararg receivers: T, block: T.() -> Unit) {
    for (receiver in receivers) receiver.block()
}

You should be able to use this function for your example perfectly. :slight_smile:


#4

@Jire Unfortunately this does not work. But I understand this is a tradeoff between clarity and convenience. I’m sure Kotlin chose clarity here by allowing only one receiver in a ‘with’ function. I must agree with Ilya that having multiple receivers will make it unclear with prop/func refers to with receiver.


#5

There was a similar discussion recently. Maybe my suggestion there could help you: About "with" statement