https://kotlinlang.org logo
#announcements
Title
# announcements
d

diesieben07

05/25/2017, 1:26 PM
because there is no
Person
as
this
in scope
a

alexfu

05/25/2017, 1:30 PM
@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

diesieben07

05/25/2017, 1:31 PM
Not really, no. The lambda you pass in is a lambda with receiver, so inside the lambda you have
john
as
this
.
a

alexfu

05/25/2017, 1:32 PM
but
this
in my example refers to
State
, not
Person
. or does it not?
d

diesieben07

05/25/2017, 1:33 PM
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

alexfu

05/25/2017, 1:37 PM
@diesieben07 so why does it work when i move the extension out of the class?
d

diesieben07

05/25/2017, 1:38 PM
Because then the extension does not require the
Person
instance.
a

alexfu

05/25/2017, 1:45 PM
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

diesieben07

05/25/2017, 1:48 PM
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

alexfu

05/25/2017, 1:53 PM
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

diesieben07

05/25/2017, 1:55 PM
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

alexfu

05/25/2017, 1:59 PM
ok, so. when the extension is inside the
Person
class, it basically can be considered as an instance variable of the
Person
class?
d

diesieben07

05/25/2017, 2:02 PM
Yes. Like I said, it's kind difficult to understand at first because you have basically two receivers.
u

umar

05/25/2017, 4:16 PM
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.
3 Views