Short example:
class MyClass {
val someName = "want this value"
val someOther = SomeOther().apply{ someName = someName }
// other stuff below
}
SomeOther
will apply the value of its own someName
to someName
, so value application makes no difference (x=x).
Q: How can I access external someName
("want this value") being inside apply
?
UPDATE
I have further doubts related to suggestion to use this.someName=someName
, below 2 code snippets, the first one works as expected, surprisingly the second fails with similar behavior as described.
First
fun main(args: Array<String>) {
class SomeOther {
var someName: String? = null
}
val someName = "want this value"
print(SomeOther().apply { this.someName = someName }.someName) // works!
}
Second
class SomeOther {
var someName: String? = null
}
class MyClass {
val someName = "want this value"
val someOther = SomeOther().apply { this.someName = someName }
fun go() = print(someOther.someName)
}
fun main(args: Array<String>) = MyClass().go() // prints null
Q: Where's the difference?
You could use the also
-function instead. It is equivalent to apply
, except it will bind your object to it
instead of this
:
val someName = "want this value"
val someOther = SomeOther().also { it.someName = someName }
The also
-function was added to Kotlin 1.1 specifially for when you do not want to shadow this
from the outer scope.
using this reference expression as below:
val someOther = SomeOther().apply { someName = [email protected] }
// reference to the outer class ---^
AND the T.apply
function is a convenient way to applying Builder Design Pattern, in this way you never need using this
or additional parameter at all, for example:
val foo = Foo().apply {
//v--- no need using `this` or any addition parameters
foo = "bar"
fuzz = "buzz"
}
class Foo {
lateinit var foo: String;
lateinit var fuzz: String
}
you can assuming apply(lambda)
which will apply an anonymous class of Function2<T,ARG,T>
instance, then you know why immediately?
in your first approach it looks like as below:
val lambda: Function2<SomeOther, String, SomeOther> = { thisRef, arg ->
thisRef.someName = arg;
// ^--- parameter is used in lambda
thisRef
}
val someName = lambda(SomeOther(), "want this value").someName
println(someName)
in your second approach it looks like as below:
class MyClass {
val lambda: Function2<SomeOther, MyClass, SomeOther> = { thisRef, arg ->
// the parameter `arg` is never used in lambda ---^
thisRef.someName = thisRef.someName
// ^--- it use thisRef's someName rather than arg's
thisRef
}
val someOther = lambda(SomeOther(), this)
}
You can access out of apply like that
class SomeOther {
var someName: String? = null
}
class MyClass {
val someName = "want this value"
val someOther = SomeOther().apply { this.someName = [email protected] }
fun go() = print(someOther.someName)
}
Try this:
val someName = "want this value"
val otherName = SomeOther().apply { this.someName = someName }
// internal someName ---^ ^
// external someName ---^
print(otherName.someName) // >>> want this name
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With