What's difference between get and [] call in Kotlin?


#1

I’m making game using Kotlin language + LibGDX library.
Kotlin version: '1.1.2-4'
LibGDX version: '1.9.6'
As official documentation says “[] operation stands for calls to member functions get() and set().”

But, when i try to run this line of code:

body.userData = animations[state[e].currentState]!!.keyFrames[frame]

I get this error:

Exception in thread "LWJGL Application" java.lang.ClassCastException: [Ljava.lang.Object; cannot be cast to [Lcom.badlogic.gdx.graphics.g2d.TextureRegion;

However when i change [] to get():

body.userData = animations[state[e].currentState]!!.keyFrames.get(frame)

Everything gets ok.

PS: “frame” is angle, converted to Int.

UPD:
I changed my code little bit

val animation: Animation = anim[e].animations[state[e].currentState]!!
val tex = animation.keyFrames[frame] // Get exception on this line anyway
body[e].body.userData = tex

“e” is entity refrence from Ashley. “body”, “anim”, and “state” are Ashley component mappers.

For those who doesn’t know what LibGDX is here is Animation class
keyFrames here is just a Java Array.

UPD 2:
I noticed that problem occurs only when i use this constructor:

Animation(float frameDuration, Array<? extends T> keyFrames)


#2

When you want to overload an operator, you have to obey some rules, which are some specific method signatures.
All the signatures can be found in Kotlin docs: Operator overloading.

A simple get() operator overloading function should be something like below:

operator fun <E> List<E>.get(index: Int): E {...}

The get() function should have some Int params, and shouldn’t return Unit.

A set() operator overloading function:

operator fun <E> MutableList<E>.set(index: Int, element: E) {...}

The set() function should have at least one Int params and another param at the last position, and return Unit.


#3

Wrong, get operators do not need an Int parameter. Ex: a Map<String, Any> can be accessed like map["string"].


#4

It’s my fault, thanks a lot.


#5

Thanks for your answer but i don’t overload anything. When i use [] operation i always get error, when i use get() everything is ok.


#6

The only explanation I can come up with is if there are multiple get methods, but not all of them are marked with the operator keyword.

Suppose you have this:

class MyClass {
    operator fun get(key: Any) = "method 1!"
    fun get(key: String) = "method 2!"
}

fun main(args: Array<String>) {
    val o = MyClass()
    println(o[23])
    println(o["23"])
    println(o.get(23))
    println(o.get("23"))
}

Only the last call will print “method 2!”.