jmfayard
09/15/2019, 5:25 PMwith(ConfigObject) { ... }
https://dev.to/jmfayard/with-configobject-language-kotlin-issparkingjoy-ic4Trevor
09/16/2019, 5:59 PMwith(something) {...}
is more appropriate than something.apply {...}
?apply
cause I didn't know about with
, so curious if there's a place where I should be using with
specificallyjmfayard
09/16/2019, 6:02 PMTrevor
09/16/2019, 6:09 PMwith(someDbQuery) { setParameter(...) }
looks nicer, I've just always used apply
cause I didn't know about with
! Just curious if there is an idiomatic preference or if they're really just interchangeableCasey Brooks
09/16/2019, 6:23 PMwith
and apply
. apply
is used for configuring an object by setting it as the receiver. with
is for “stepping into the scope” of an object to access its members while doing something else.
You’d more commonly see with
as a function expression, and apply
tacked onto the return value of a function or expressionTrevor
09/16/2019, 6:32 PMsuresh
09/16/2019, 9:16 PMI don’t get this part. Bothis for “stepping into the scope” of an objectwith
with
and apply
do stepping into the scope and it’s clear from their function signature.
with(receiver: T, block: T.() -> R): R
T.apply(block: T.() -> Unit): T
IMHO, the main difference is, with with()
function you can return any value (which is returned by the lambda) if it’s used in an expression but apply always returns this
.
with(ConfigObject) { ... }
pattern can also be used with apply
object Config {
const val NAME = "KOTLIN"
fun String.isAJoy() = println("Language $NAME is awesome!")
}
fun main() {
Config.apply {
NAME.isAJoy()
}
}
Casey Brooks
09/16/2019, 9:30 PMwith
implies that you are entering into a specific “scope”, for the purposes of doing stuff within that scope. apply
is technically “stepping into a scope” because the object is set as the receiver, but the meaning behind it isn’t to enter a scope and do stuff within that scope. The meaning of apply
is that you are succinctly applying values to the receiver object.
class FactoryObject {
var one: String = ""
var two: String = ""
var three: String = ""
}
// apply values to FactoryObject, and return that object.
// Semantically, you're returning a value, and modifying
// it right before returning it. Within the scope of
// FactoryObject, you're setting values, but not really
// "doing stuff"
fun createObject_Apply() = FactoryObject().apply {
one = ""
two = ""
two = ""
}
// looks pretty much like the other, but it returns
// Unit. You've "stepped into the scope" of FactoryObject,
// and inside there you're expected to _do_ stuff, not
// _set_ stuff. Whatever you're doing is free to return
// any value it needs, just as if it were any other function
fun createObject_With() = with(FactoryObject()) {
one = ""
two = ""
two = ""
}