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

为什么Jetpack Compose中操作局部变量的函数可得到正确结果?Code B是否正确?

问题解答

1、为什么Code A测试时始终得到正确结果

你当前测试场景下只触发了初始组合,没有触发过重组,所以看起来结果正常:

  • Code A中的items是普通局部变量,每次ListWithBug执行时都会被初始化为0
  • 初始组合阶段,所有组合代码都会全量执行,Column循环遍历10个元素时,items++完整执行了10次,最终items值为10,和预期一致

一旦触发重组(比如新增可点击按钮修改页面状态,触发ListWithBug重新执行),就会出现错误:

  • 重组时Compose会跳过输入没有变化的组件,此时Column中所有Text的输入参数都没有变化,会被跳过执行,对应的items++也不会执行,最终items的值会停留在初始化的0,显示结果错误
  • 更复杂的重组场景下,Compose的执行顺序、跳过规则都是不可预测的,局部变量的计数结果会完全不符合预期。

2、Code B的写法是否正确

完全错误,问题比Code A更严重:

  • items被声明为remember包裹的状态变量,重组时不会被重置初始值,每次重组只要循环里的代码执行,items就会被额外累加一次:初始组合后值为10,第一次重组后变成20,第二次变成30,数值会持续漂移,完全不符合预期
  • 你在组合过程中修改了items状态,而items又被下方的Text读取,这会触发无限重组循环:修改items → 触发重组 → 再次修改items → 再次触发重组,最终会导致页面卡死、ANR
  • 本质上两种写法都属于在组合过程中引入了副作用,违反了Compose可组合函数必须无副作用的原则,这类计数需求应该直接用myList.size,如果需要做额外的副作用操作,必须使用SideEffect、LaunchedEffect等官方提供的副作用API包裹,不能直接写在组合流程中。

内容的提问来源于stack exchange,提问作者HelloCW

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.01 07:09:05