https://kotlinlang.org logo
#getting-started
Title
# getting-started
o

oday

11/19/2020, 9:06 AM
I know that val cannot be reassigned, but how would I for example send a variable to a function to do something with it?
Copy code
private fun resetCounterAndGame(counter: Int) {
    if (counter == 2) {
        gameButtonText.set(resProvider.getString(R.string.try_another_number))
        gameStarted = false
        counter = 0 <--- val cannot be reassigned of course
    }
}
w

wbertan

11/19/2020, 9:08 AM
Can you make it return the new value for
counter
?
o

oday

11/19/2020, 9:08 AM
yea sure I can, but then I would be doing
thingImTryingToCount = resetGameAndCounter(thingImTryingToCount)
right?
yea cause I wanna do this for several counters
I think the function is doing too much
I can have an extension function that can be like
counter.reset()
and if
this == 2 return 0 else return this
w

wbertan

11/19/2020, 9:15 AM
Could you use a
MutableStateFlow
instead? So you can pass the reference and set a new value, and whenever reads the state flow would always pick the latest value.
o

oday

11/19/2020, 9:16 AM
hm im not really using coroutines right now
ill check it out
v

Vampire

11/19/2020, 9:39 AM
Your problem is not so much that
val
cannot be reassigned, but that you confuse pass-by-value and pass-by-reference.
👍 2
You don't push a variable to the method, but only its value
In case of an object you are passing the reference to that object in and can modify the state of that object
But for an
Int
you just pass the
2
You can probably do something like this:
Copy code
private fun resetCounterAndGame(counter: KMutableProperty<Int>) {
    if (counter.getter.call() == 2) {
        gameButtonText.set(resProvider.getString(R.string.try_another_number))
        gameStarted = false
        counter.setter.call(0)
    }
}
and then pass the reference to the field with
resetCounterAndGame(::counter)
or similar, but I would strongly advice to not do this.
t

Tobias Berger

11/19/2020, 9:47 AM
there are some ways you could do this. • you could return an object containing all the new values you want to set and do so after the function call • you could pass setter callbacks to the functions that set a new value when called • you can wrap the mutable values in an object that is passed to the function and then modified inside Depending on your use case, each of these can be the perfect solution or a real code smell.
1️⃣ 1
actuall I also thougt of the KMutablePropert approach. I wouldn't sa it's a no-go, especially since reflection in Kotlin offers a lot more type safety than in Java. But it can still have some performance impact which might be undesireable in a mobile application and also it would only work with properties, not with local variables.
v

Vampire

11/19/2020, 9:56 AM
Yeah, probably better to give a setter instead of using reflection, but still a bit smelly 😄
Copy code
private fun resetCounterAndGame(counter: Int, counterSetter: (Int) -> Unit) {
    if (counter == 2) {
        counterSetter(0)
    }
}

fun main() {
    var counter = 1
    println(counter)
    resetCounterAndGame(counter++) { counter = it }
    println(counter)
    resetCounterAndGame(counter++) { counter = it }
    println(counter)
}
=>
Copy code
1
2
0
k

Kirill Grouchnikov

11/19/2020, 2:15 PM
Ah, the good old Fortran days where you could pass "4" as an integer argument, and then the function could override its value to 5. Then after the function returns, everywhere you had 4 was treated as 5. Yeah, you don't want that.
😆 1
r

Ryan

11/19/2020, 2:47 PM
use an AtomicInt
1385 Views