it's still not intuitive to me when to use double-...
# getting-started
y
it's still not intuitive to me when to use double-colon (
::
) vs dot (
.
) in access paths. I invariably have to try both until the compiler is satisfied. is there a good explanation of this somewhere?
s
There's probably someone with a better explanation, but I can have a go: If you're wanting to access the member functions/fields/properties of an object, then you would normally use the
.
operator (or
?.
if the reference you have might be null) eg:
Copy code
val myList = ArrayList<String>

val x = myList.size
In the first line, you are creating an object (instance) called
myList
of the type (class)
ArrayList<String>
. In the second line, you're using the
.
operator to access the
size
property that instances of
ArrayList<String>
have. So x will be assigned the same value as the size property of that given ArrayList instance
myList
, Rule of thumb, 99 times out of 100 you'll likely want a
.
The
::
is used if you want to make a reference to a function, maybe because you want to pass it as a parameter to another function - you use it to help specify where that particular function is, a bit like a path. In C++ it used to be called a scope resolution operator, I'm not sure if its got the same name in kotlin. An example of how you would possibly use that:
Copy code
fun myFunction() {
    println("myFunction has been called")
}

fun anotherFunction( aFunctionParameter: () -> Unit) {
    aFunctionParameter()
}

fun main() {

    anotherFunction(::myFunction)    

}
The first function has no parameters, no return value, andd prints out a line. The second function has a single parameter, called
aFunctionParameter
and it's type is another function, that has no parameters, and no return value (it wants a function with the same signature as the first function). The
main
function wants to call
anotherFunction
but in order to do so it needs to give it a parameter. This is where the
::
symbol comes in. You can use
::
and the name of the function you want to pass in order to create a reference to that function which can be passed as a parameter. In some instance you might see things like
this@MyClass::myFunction
but don't worry about that for now unless you really need to - that sort of thing is when you need to provide more information about the overall path of the function you want a reference to - ie maybe it belongs to a class or something.
thank you color 1
h
someObject.property
and
someObject.method(<args>)
return the result of the method/getter. •
someObject::property
and
someObject::method
return a lambda*. When it is invoked (with suitable arguments in case it's a method) it returns the result of the method/getter.
someObject::property
and
{ someObject.property }
are basically the same. Similarly
someObject::method
and
{ <args> -> someObject.method(<args>) }
SomeClass::property
and
SomeClass::method
also return a lambda*. However in this case it should be invoked with as the first argument an instance of the class (and in case of the method further argument associated with the method). When invoked, it returns the result of the method/getter called on the given instance.
SomeClass::property
and
{ instance: SomeClass -> instance.property }
are basically the same. Similarly
SomeClass:method
and
{ instance: SomeClass, <args> -> instance.method(<args>) }
. *) when I say "returns a lambda", that's not the whole story, you can do more with it than you can with a regular lambda, but that's probably not what you're after. Here's a playground example I also sometimes try both
.
and
::
until the compiler is happy, but that's usually in cases where my methods or getters return lambdas themselves, or when some reflection is involved. Usually I understand the compiler once I got it right, so this happens less and less often nowadays.
thank you color 1
y
I also sometimes try both . and :: until the compiler is happy, but that's usually in cases where my methods or getters return lambdas themselves, or when some reflection is involved
indeed that's the situation I'm talking about here. thanks for the playground example
k
The syntax I find least intuitive is
SomeClass::class
. Having been a Java developer, where it would be just
SomeClass.class
and
someInstance.getClass()
, I would have expected the Kotlin equivalents to be
SomeClass.class
and
someInstance.class
. In every other context, the
::
operator returns a function/property reference or something similar. Huib said:
SomeClass::property
and
{ instance: SomeClass -> instance.property }
are basically the same
True, except the same syntax can't be used with
SomeClass::class
.
j
I disagree with
The syntax I find least intuitive is
SomeClass::class
Indeed, I think Java is doing it wrong as I don't know why using property accessors to get something is not a property can be intuitive. On Kotlin it is clear what you get (some
K
prefixed Kotlin object): A
KClass
,
KFunctionN
, etc
I would like to get something like
Foo::constructor
tho
👍 2