Beginner question - any idea why the value from lemonSize in SELECT is not carrying over to SQUEEZE when switching lemonadeState? Any help is greatly appreciated :)
The app/code is part of intro to Kotlin course by Google which is for creating a lemonade app that rotates between screens https://developer.android.com/codelabs/basic-android-kotlin-training-project-lemonade?continue=https%3A%2F%2Fdeveloper.android.com%2Fcourses%2Fpathways%2Fandroid-basics-kotlin-four%23codelab-https%3A%2F%2Fdeveloper.android.com%2Fcodelabs%2Fbasic-android-kotlin-training-project-lemonade#0
Here's where i think the problem is (I attached logs below that):
// Default lemonSize to -1
private var lemonSize = -1
// Default the squeezeCount to -1
private var squeezeCount = -1
private var lemonTree = LemonTree()
when (lemonadeState) {
SELECT -> {
Log.d(TAG, "lemonadeState at beginning of SELECT *should be SELECT* lemonadeState = $lemonadeState")
// Set the lemonSize (the number of squeezes needed) by calling the pick() method
var lemonSize = LemonTree()//UPDATE
Log.d(TAG, "randomly generated lemonSize using LemonTree -> lemonSize = $lemonSize")
// Setting the squeezeCount (the number of times the user has squeezed the lemon) to 0.
squeezeCount = 0
Log.d(TAG, " setting squeezeCount to 0 -> squeezeCount = $squeezeCount")
// Transition to the SQUEEZE state
lemonadeState = SQUEEZE
Log.d(TAG, "lemonadeState at bottom of SELECT *should be SQUEEZE* lemonadeState = $lemonadeState")
}
// TODO: When the image is clicked in the SQUEEZE state the squeezeCount needs to be
// INCREASED by 1 and lemonSize needs to be DECREASED by 1.
// - If the lemonSize has reached 0, it has been juiced and the state should become DRINK
// - Additionally, lemonSize is no longer relevant and should be set to -1
SQUEEZE -> {
Log.d(TAG, "at top of SQUEEZE *lemonSize should be 2-4* lemonSize = $lemonSize")
Log.d(TAG, "at top of SQUEEZE *lemonadeState should be SQUEEZE* lemonadeState = $lemonadeState")
//squeezeCount needs to be INCREASED by 1
squeezeCount += 1
//lemonSize needs to be DECREASED by 1.
Log.d(TAG, "decreasing lemonSize by 1")
Log.d(TAG, "lemonSize before decreasing by 1 lemonSize = $lemonSize")
lemonSize = lemonSize - 1
Log.d(TAG, "lemonSize after decreasing by 1 lemonSize = $lemonSize")
//lemonSize = 0//REMOVE once done with testing
//Log.d(TAG, "lemonSizeHere = $lemonSize ** REMOVE")
//If the lemonSize has reached 0, it has been juiced and the state should become DRINK
if (lemonSize == 0) {
lemonadeState = DRINK
//lemonSize = -1
Log.d(TAG, "lemonadeState when lemonSize == 0 lemonadeState = $lemonadeState")
}
}
/**
* A Lemon tree class with a method to "pick" a lemon. The "size" of the lemon is randomized
* and determines how many times a lemon needs to be squeezed before you get lemonade.
*/
class LemonTree {
fun pick(): Int {
return (2..4).random()
}
}
Logs:
2022-06-17 16:20:46.837 8549-8578/com.example.lemonade W/OpenGLRenderer: Failed to initialize 101010-2 format, error = EGL_SUCCESS
2022-06-17 16:20:49.788 8549-8549/com.example.lemonade D/MainActivity: lemonadeState at beginning of SELECT *should be SELECT* lemonadeState = select
2022-06-17 16:20:49.789 8549-8549/com.example.lemonade D/MainActivity: randomly generated lemonSize using LemonTree -> lemonSize = com.example.lemonade.LemonTree@5c31497
2022-06-17 16:20:49.790 8549-8549/com.example.lemonade D/MainActivity: setting squeezeCount to 0 -> squeezeCount = 0
2022-06-17 16:20:49.793 8549-8549/com.example.lemonade D/MainActivity: lemonadeState at bottom of SELECT *should be SQUEEZE* lemonadeState = squeeze
2022-06-17 16:21:04.177 8549-8549/com.example.lemonade D/MainActivity: at top of SQUEEZE *lemonSize should be 2-4* lemonSize = -1
2022-06-17 16:21:04.179 8549-8549/com.example.lemonade D/MainActivity: at top of SQUEEZE *lemonadeState should be SQUEEZE* lemonadeState = squeeze
2022-06-17 16:21:04.184 8549-8549/com.example.lemonade D/MainActivity: lemonSize before decreasing by 1 lemonSize = -1
2022-06-17 16:21:04.186 8549-8549/com.example.lemonade D/MainActivity: lemonSize after decreasing by 1 lemonSize = -2
So you're creating a top-level variable called lemonSize
that's initialised to -1
:
// Default lemonSize to -1
private var lemonSize = -1
That var is an Int
which is inferred by the fact you assigned an integer value to it. This is meant to be size of your current lemon, right?
But inside your SELECT
branch, you're doing this:
// Set the lemonSize (the number of squeezes needed) by calling the pick() method
var lemonSize = LemonTree()//UPDATE
There's two problems here - first, you're creating a new variable called lemonSize
that only exists within the scope of those curly braces, the code that's executed when your state is SELECT
. Whatever you do with that variable, it'll disappear once you exit that code block.
So when you reach the SQUEEZE
branch, when that refers to lemonSize
it's looking at the top-level one, which is still -1
. The lemonSize
variable you created in SELECT
is gone, and wouldn't be visible to the SQUEEZE
block anyway.
So what you should be doing in SELECT
is changing the value of that top-level 'lemonSize' variable (which is what you're doing for squeezeCount
and lemonadeState
anyway):
// no 'var' this time, we're setting the top-level one
// THIS LINE WON'T WORK THOUGH! see below
lemonSize = LemonTree()
and here's where you run into your other problem - this won't work, because you're calling LemonTree()
which is the constructor for the LemonTree
class. You're creating a LemonTree
object and assigning it to the lemonSize
variable - which as we saw earlier, has been inferred to hold an Int
type. And a LemonTree
is not an Int
! It can't go there
Your current code runs fine because you're basically creating a new local variable, that happens to be called lemonSize
, and assigning a LemonTree
to it - so you've created a variable with an inferred LemonTree
type. And you don't do anything with it, so it's never a problem (although in your log you can see it prints out weird - com.example.lemonade.LemonTree@5c31497
means it's a LemonTree
object with a reference ID, ain't a number!)
So like the comment above that line says, you really need to be calling pick()
to get your lemonSize
. And you could create a new LemonTree
object right there to pick from - but you already put one in a top-level variable, lemonTree
. You probably just want to use that, right?
In the end, you probably want to do this:
SELECT -> {
// pick a new current lemon and record its size
lemonSize = lemonTree.pick()
...
}
and now your top-level lemonSize
state variable has a new value everything can see.
Hope that makes sense! There's a few concepts to get familiar with here
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.