You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Kotlin柠檬水应用when状态切换时lemonSize值异常变化问题

问题:lemonadeState状态切换时lemonSize值异常

故障原因

这是典型的Kotlin变量作用域误用,和状态流转逻辑无关。
你在SELECT分支里写的val lemonSize = 2,是在SELECT分支的代码块内部定义了一个局部变量,这个变量的生效范围仅限当前SELECT大括号包裹的代码段,和SQUEEZE分支里访问的类层级全局lemonSize变量完全是两个独立的东西。
你在SELECT分支里给这个局部变量赋值2,等SELECT分支执行完,局部变量就会被回收,赋值根本没有同步到全局的lemonSize上。而全局lemonSize在上一轮制作流程走到DRINK状态时被设置为了-1,所以切到SQUEEZE分支读取全局变量时,拿到的自然是-1,和你预期的2不符。
你之前注释掉的val lemonSize = LemonTree()也是完全一样的错误,多写了val关键字导致重新声明了局部变量,没有修改全局状态。

修复方案

删掉SELECT分支里给lemonSize赋值语句前面的val关键字,不要新建局部变量,直接对已有的全局lemonSize赋值即可:

when (lemonadeState) {
    SELECT -> {
        Log.d(TAG, "lemonadeState at beginning of SELECT *should be SELECT* lemonadeState = $lemonadeState")

        // 去掉前面的val,直接给全局变量赋值,后续恢复原pick()逻辑时也不要加val
        lemonSize = 2
        Log.d(TAG, " setting lemonSize to 2 -> lemonSize = $lemonSize")

        squeezeCount = 0
        Log.d(TAG, " setting squeezeCount to 0 -> squeezeCount = $squeezeCount")

        lemonadeState = SQUEEZE
        Log.d(TAG, "lemonadeState at bottom of SELECT *should be SQUEEZE* lemonadeState = $lemonadeState")
    }

    SQUEEZE -> {
        // 原有逻辑不用改,修复后这里读到的lemonSize就会是你设置的2
        Log.d(TAG, "at top of SQUEEZE *lemonSize should be 2* lemonSize = $lemonSize")
        Log.d(TAG, "at top of SQUEEZE *lemonadeState should be SQUEEZE* lemonadeState = $lemonadeState")

        squeezeCount += 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")

        if (lemonSize == 0) {
            lemonadeState = DRINK
            lemonSize = -1
            Log.d(TAG, "lemonadeState when lemonSize == 0 lemonadeState = $lemonadeState")
        }
    }
}

日志对应验证

你贴的运行日志完全可以印证这个问题:

  • SELECT分支执行时打印的setting lemonSize to 2 -> lemonSize = 2,访问的是刚声明的局部变量,所以值显示正确
  • SELECT分支执行完毕后局部变量销毁,全局lemonSize仍保留上一轮结束时设置的-1,所以进入SQUEEZE分支的第一行日志就打出了at top of SQUEEZE *lemonSize should be 2* lemonSize = -1,完全符合作用域规则的运行表现。
  • 日志里的OpenGLRenderer渲染警告是模拟器通用提示,和本次业务逻辑bug无关。

内容的提问来源于stack exchange,提问作者Moya.A

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.30 06:12:13