because there is no `Person` as `this` in scope
# announcements
d
because there is no
Person
as
this
in scope
a
@diesieben07 from what i can tell,
with(john) { state.isSingle }
basically does the same thing as
john.state.isSingle
right?
with
takes an object and a block and then executes that block with the object as the argument
d
Not really, no. The lambda you pass in is a lambda with receiver, so inside the lambda you have
john
as
this
.
a
but
this
in my example refers to
State
, not
Person
. or does it not?
d
That's the strange thing about extension functions/properties inside a class: You basically have two
this
. You can access the "`Person` `this`" inside the extension property with
this@Person
.
a
@diesieben07 so why does it work when i move the extension out of the class?
d
Because then the extension does not require the
Person
instance.
a
sorry, i’m still not getting it. when i call
person.state
person
is an instance and so is
state
. so why is the extension property unavailable from that?
d
Because the compiler has no way of knowing that
person
is the
Person
instance to use for the extension property. Say you have a
val person
and a
val person2
. Then you do
val state = person.state
. If you now call
state.isSingle
the compiler has no way of knowing which
Person
to use, and making it guess is a terrible idea. You have to be explicit about it.
a
I’m still missing something. so what’s the major difference between declaring it outside the class vs inside the class. If i wrap the extension with
companion object
, wouldn’t that effectively be the same as declaring it outside of the class? (i.e. statically and therefore doesn’t require an instance of person)
d
A companion object is still an object, it's methods have access to a
this
, which is the companion object instance. So you would need
with (MyClass.Companion) { /* call extension property */ }
Only top-level functions do not have a receiver (unless they are extension functions of course)
a
ok, so. when the extension is inside the
Person
class, it basically can be considered as an instance variable of the
Person
class?
d
Yes. Like I said, it's kind difficult to understand at first because you have basically two receivers.
u
Extensions functions inside class compile to this class' non-static methods, and the first argument is declared receiver of extension. So you cannot use them outside of current object's scope. Top level extensions compile to static functions, so you can call them from everywhere.