news 2026/7/1 20:48:47

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/6/30 1:30:31

计算机毕业设计springboot小区疫情期间物资配送 基于SpringBoot的封控社区生活物资保供平台 疫情封闭期间小区生活物资在线订购与配送系统

计算机毕业设计springboot小区疫情期间物资配送7y509 &#xff08;配套有源码 程序 mysql数据库 论文&#xff09; 本套源码可以在文本联xi,先看具体系统功能演示视频领取&#xff0c;可分享源码参考。 2020 年初突如其来的新冠疫情让“足不出户”成为常态&#xff0c;小区大门…

作者头像 李华
网站建设 2026/6/26 23:38:37

基于SpringBoot的小区物业管理系统毕设源码

博主介绍&#xff1a;✌ 专注于Java,python,✌关注✌私信我✌具体的问题&#xff0c;我会尽力帮助你。 一、研究目的 本研究旨在设计并实现一个基于SpringBoot框架的小区物业管理系统&#xff0c;以满足现代小区物业管理的高效、便捷和智能化需求。具体研究目的如下&#xff…

作者头像 李华
网站建设 2026/6/30 18:02:36

大语言模型内部揭秘:从分词到文本生成的技术之旅(建议收藏)

文章解析了大语言模型从分词到文本生成的完整技术链路&#xff0c;详细介绍了Tokenization机制、人类与机器语言表示差异&#xff0c;以及神经网络应用、规模化力量等核心技术优势。同时展望了模型在知识管理、智能对话等领域的应用前景&#xff0c;并指出技术局限性与使用建议…

作者头像 李华
网站建设 2026/6/29 21:44:11

导师严选!AI论文工具 千笔 VS speedai,本科生写作神器!

随着人工智能技术的迅猛发展&#xff0c;AI辅助写作工具已逐渐成为高校学生完成毕业论文的重要帮手。从开题到撰写&#xff0c;再到查重与修改&#xff0c;AI正在深刻改变学术写作的方式。然而&#xff0c;面对市场上琳琅满目的AI工具&#xff0c;许多本科生在选择时感到无所适…

作者头像 李华
网站建设 2026/6/29 22:06:57

盲盒小程序热门玩法分析(附开发者落地要点)

随着潮玩经济持续升温&#xff0c;盲盒小程序凭借轻量化、高裂变、低门槛的优势&#xff0c;成为开发者入局潮玩赛道的核心载体。其核心竞争力不在于界面设计&#xff0c;而在于“惊喜感可落地玩法技术适配”&#xff0c;热门玩法均围绕“未知性、社交性、收藏性”三大核心展开…

作者头像 李华