news 2026/6/10 14:28:28

Compose 中的状态可变性体系

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Compose 中的状态可变性体系

您说得非常对!您的直觉是正确的。Compose 确实有类似 Kotlin 集合的可变/不可变概念,但是实现方式不同。

1.Compose 中的状态可变性体系

Kotlin 集合的类比:

// Kotlin 集合valimmutableList:List<String>=listOf("A","B")// 只读valmutableList:MutableList<String>=mutableListOf("A","B")// 可修改// Compose 状态(类似但不同)valreadOnlyState:State<Int>=...// 只读状态接口valmutableState:MutableState<Int>=...// 可变状态接口

2.Compose 的实际状态类型

2.1State<T>接口(只读)

// State 接口定义(简化版)interfaceState<outT>{valvalue:T// 只读属性}

2.2MutableState<T>接口(可变)

// MutableState 接口定义(简化版)interfaceMutableState<T>:State<T>{overridevarvalue:T// 可写属性}

3.创建只读状态的方法

虽然 Compose 没有stateOf()函数,但有多种方式创建只读状态:

方法1:使用val+mutableStateOf

@ComposablefunReadOnlyExample1(){// 创建只读状态(对组件内部)valcounter:State<Int>=remember{mutableStateOf(0)}// 使用Text("Count:${counter.value}")// ✅ 可以读取// counter.value = 5 // ❌ 编译错误(虽然是 MutableState,但用 val 声明)}

方法2:参数传递(来自父组件)

@ComposablefunParent(){varcounterbyremember{mutableStateOf(0)}// 传递给子组件时是只读的 State<Int>Child(counter=counter)}@ComposablefunChild(counter:State<Int>){// 这里 counter 是只读的Text("Count:${counter.value}")}

方法3:使用derivedStateOf(计算状态)

@ComposablefunDerivedExample(){varinputbyremember{mutableStateOf("")}// 派生状态是只读的 State<Boolean>valisValid:State<Boolean>=remember{derivedStateOf{input.length>5}}Text("Valid:${isValid.value}")}

4.完整的可变/不可变对比

创建方式对比:

@ComposablefunStateComparison(){// ========== 可变状态 ==========// 方式1:使用 var + by(最常用)varmutable1byremember{mutableStateOf(0)}// 方式2:显式 MutableState 类型valmutable2:MutableState<Int>=remember{mutableStateOf(0)}// 方式3:类型化版本varmutable3byremember{mutableIntStateOf(0)}// ========== 只读状态 ==========// 方式1:用 val 声明(对当前组件只读)valreadOnly1:State<Int>=remember{mutableStateOf(0)}// 方式2:派生状态valreadOnly2:State<Int>=remember{derivedStateOf{mutable1*2}}// 方式3:从参数获得// @Composable fun Child(state: State<Int>)}

使用方式对比:

// 可变状态使用mutable1=10// ✅ 直接赋值mutable2.value=20// ✅ 通过 .value 赋值mutable3=30// ✅ 直接赋值// 只读状态使用valvalue1=readOnly1.value// ✅ 只能读取valvalue2=readOnly2.value// ✅ 只能读取// readOnly1.value = 40 // ❌ 编译错误

5.为什么 Compose 设计成这样?

设计理念:

  1. 简化 API:只需要记住mutableStateOf
  2. 类型安全:通过接口区分可变/不可变
  3. 灵活转换:同一个对象可以在不同上下文中可变或只读

实际示例:

@ComposablefunCounterScreen(){// 在父组件中是可变的varcountbyremember{mutableStateOf(0)}Column{// 传递给按钮组件时是只读的CounterDisplay(count=count)// 传递给控制组件时是可变的CounterControls(count=count,onCountChange={count=it})}}// 只读展示组件@ComposablefunCounterDisplay(count:Int){Text("Count:$count")}// 可变控制组件@ComposablefunCounterControls(count:MutableState<Int>,// 或者用回调函数方式onCountChange:(Int)->Unit){Button(onClick={onCountChange(count+1)}){Text("Increment")}}

6.与其他状态管理方式的对比

Compose 状态 vs Flow/LiveData:

@ComposablefunStateVsFlow(){// Compose 状态(同步,直接)varcomposeStatebyremember{mutableStateOf(0)}// Flow(异步,需要收集)valflowStatebyflow.collectAsState(initial=0)// LiveData(需要转换)valliveDataStatebyliveData.observeAsState()// 它们都实现了 State<T> 接口!valanyState:State<Int>=composeState// 实际上需要包装}

7.实际应用建议

何时用可变状态:

// 组件内部管理状态时@ComposablefunMyComponent(){varisExpandedbyremember{mutableStateOf(false)}// ✅vartextbyremember{mutableStateOf("")}// ✅}

何时用只读状态:

// 1. 从父组件接收状态@ComposablefunChild(isVisible:Boolean,text:String)// 基本类型参数// 2. 或接收 State 对象@ComposablefunChild(state:State<Data>)// 复杂对象// 3. 派生计算状态@ComposablefunExample(){varinputbyremember{mutableStateOf("")}valisValid=input.length>5// 不需要 State,每次重组计算valcharCountbyremember{derivedStateOf{input.length}}// 需要缓存时}

8.总结回答您的问题

您的感觉是对的!Compose 确实有类似 Kotlin 集合的可变/不可变概念:

Kotlin 集合Compose 状态说明
List<T>State<T>只读接口
MutableList<T>MutableState<T>可变接口
listOf()没有直接对应需要其他方式创建只读状态
mutableListOf()mutableStateOf()创建可变状态

关键区别

  • Kotlin:listOf()mutableListOf()是两个不同的函数
  • Compose:只有mutableStateOf()一个创建函数,通过接口类型声明方式val/var)控制可变性

简单记忆

  • 需要修改状态 →var x by mutableStateOf()
  • 只需要读取状态 →val x: State<T> = ...或基本类型参数
  • Compose 的MutableState就像 Kotlin 的MutableList,而State就像List
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/5/21 8:11:35

开题报告 springboot和vue电子万年历

目录技术栈概述系统功能模块技术实现要点特色功能扩展项目技术支持可定制开发之功能亮点源码获取详细视频演示 &#xff1a;文章底部获取博主联系方式&#xff01;同行可合作技术栈概述 SpringBoot和Vue结合的电子万年历系统采用前后端分离架构。SpringBoot作为后端框架提供RE…

作者头像 李华
网站建设 2026/6/10 13:31:58

Claude Code 从入门到精通(八):MCP连接外部真实系统

Claude Code 从入门到精通&#xff08;八&#xff09;&#xff1a;MCP连接外部真实系统 MCP&#xff08;Model Context Protocol&#xff0c;模型上下文协议&#xff09;是 Anthropic 为 Claude Code 打造的标准化外部工具连接协议&#xff0c;核心价值在于打破 AI 与外部系统…

作者头像 李华
网站建设 2026/5/29 13:13:26

Jmeter接口测试:使用指南(上)

&#x1f345; 点击文末小卡片&#xff0c;免费获取软件测试全套资料&#xff0c;资料在手&#xff0c;涨薪更快 Jmeter是一款小巧&#xff0c;轻便、开源的性能测试工具&#xff0c;它也可以很方便的进行接口测试。 下面我就带大家学习下jmeter接口测试。 一、Jmeter简介 J…

作者头像 李华
网站建设 2026/6/10 13:30:24

Selenium自动化测试入门:cookie 处理

&#x1f345; 点击文末小卡片&#xff0c;免费获取软件测试全套资料&#xff0c;资料在手&#xff0c;涨薪更快driver.get_cookies() # 获得cookie 信息driver.get_cookies(name) # 获得对应name的cookie信息add_cookie(cookie_dict) # 向cookie 添加会话信息delete_cookie(na…

作者头像 李华