news 2026/4/25 12:21:57

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/4/22 22:15:37

开题报告 springboot和vue毕业生信息收集系统

目录系统背景技术选型核心功能创新点预期成果项目技术支持可定制开发之功能亮点源码获取详细视频演示 &#xff1a;文章底部获取博主联系方式&#xff01;同行可合作系统背景 毕业生信息收集系统旨在简化高校对学生毕业去向、就业状态等数据的统计与管理。传统方式依赖Excel或…

作者头像 李华
网站建设 2026/4/25 4:30:23

计算机毕业设计springboot壁纸网站 基于SpringBoot的高清壁纸资源分享平台的设计与实现 SpringBoot+MySQL构建的个性化桌面壁纸管理系统

计算机毕业设计springboot壁纸网站32zp4 &#xff08;配套有源码 程序 mysql数据库 论文&#xff09; 本套源码可以在文本联xi,先看具体系统功能演示视频领取&#xff0c;可分享源码参考。 壁纸&#xff0c;是数字生活第一眼看到的风景。随着屏幕分辨率不断攀升&#xff0c;用…

作者头像 李华
网站建设 2026/4/22 13:58:45

让AI帮你消灭一整类重复劳动 - Skill能力模块化实战指南,从小白到高手的进阶之路

文章探讨了如何通过AI和Skill能力模块化减少编程中的重复劳动。作者提出将最佳实践、流程和规则封装成可复用的能力单元&#xff0c;让AI从一次性工具进化为理解业务的智能助手。文章详细介绍了DAO层CRUD、基础服务和Git工作流等Skill实现&#xff0c;指出未来开发者应专注于问…

作者头像 李华
网站建设 2026/4/23 17:08:49

开题报告 springboot和vue考勤管理系统

目录系统概述技术栈说明核心功能模块创新点与优势应用场景项目技术支持可定制开发之功能亮点源码获取详细视频演示 &#xff1a;文章底部获取博主联系方式&#xff01;同行可合作系统概述 SpringBoot和Vue考勤管理系统是一款基于前后端分离架构的现代化管理工具&#xff0c;后…

作者头像 李华
网站建设 2026/4/21 15:25:27

当菜单选择变得危险:揭露Zomato小部件中的XSS漏洞

仅限会员阅读的故事 “当菜单选择变得危险&#xff1a;揭露Zomato小部件中的XSS漏洞” Aman Sharma 4分钟阅读 2025年12月12日 2次收听分享 在探查热门餐厅发现平台Zomato的数字基础设施时&#xff0c;安全研究员pr0tagon1st偶然发现了一个令人担忧的问题。 该平台的两个小部件…

作者头像 李华
网站建设 2026/4/23 15:50:03

力扣解题-两数之和

力扣解题-两数之和 题目&#xff1a; 给定一个整数数组 nums 和一个整数目标值 target&#xff0c;请你在该数组中找出 和为目标值 target 的那 两个 整数&#xff0c;并返回它们的数组下标。 你可以假设每种输入只会对应一个答案&#xff0c;并且你不能使用两次相同的元素。…

作者头像 李华