news 2026/8/29 2:38:03

kotlin和compose中使用by

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
kotlin和compose中使用by

by是 Kotlin 中的一个关键字,表示委托(delegation)。它的含义是:“将这个属性的 getter 和 setter 委托给另一个对象处理”。

1.基本概念

// 没有 by:直接赋值vala="Hello"// a 存储字符串本身// 有 by:委托valbbydelegateObject// b 的读写操作委托给 delegateObject 处理

2.by在 Compose 中的具体含义

在 Compose 中,by通常与mutableStateOf一起使用:

// 没有 by:myText 是一个 MutableState<String> 对象valmyText=remember{mutableStateOf("Hello")}// 使用:myText.value = "World" 需要 .value// 有 by:myText 看起来是一个普通的 String,但实际上委托给了 MutableStatevarmyTextbyremember{mutableStateOf("Hello")}// 使用:myText = "World" 不需要 .value,看起来像普通变量

3.底层原理:属性委托

Kotlin 的委托机制:

// 自定义委托类classSimpleDelegate<T>(privatevarvalue:T){// getValue 方法:当读取属性时调用operatorfungetValue(thisRef:Any?,property:KProperty<*>):T{println("读取属性:${property.name}")returnvalue}// setValue 方法:当设置属性时调用(仅 var)operatorfunsetValue(thisRef:Any?,property:KProperty<*>,newValue:T){println("设置属性:${property.name}=$newValue")value=newValue}}// 使用委托varmessagebySimpleDelegate("Hello")// 实际执行:message = SimpleDelegate("Hello")println(message)// 调用 getValue(),输出: Hellomessage="World"// 调用 setValue("World")

4.Compose 中mutableStateOf的委托实现

mutableStateOf返回的对象实现了State接口,它提供了getValuesetValue操作符:

// 简化的 State 接口interfaceState<T>{varvalue:ToperatorfungetValue(thisRef:Any?,property:KProperty<*>):ToperatorfunsetValue(thisRef:Any?,property:KProperty<*>,value:T)}// 实际使用varcountbymutableStateOf(0)// 相当于:// val countState = mutableStateOf(0)// var count: Int// get() = countState.getValue(this, ::count)// set(value) = countState.setValue(this, ::count, value)

5.为什么需要by

没有by的缺点:

// 方式1:不使用委托valcountState=remember{mutableStateOf(0)}// 使用繁琐:countState.value++// 需要 .valueif(countState.value>5)// 需要 .valuecountState.value=10// 需要 .value

by的优点:

// 方式2:使用委托varcountbyremember{mutableStateOf(0)}// 使用简洁:count++// 看起来像普通变量if(count>5)// 看起来像普通变量count=10// 看起来像普通变量

6.by的其他使用场景

除了 Compose,by还有多种用途:

// 1. 惰性初始化(lazy)valheavyObjectbylazy{println("首次访问时初始化")HeavyObject()}// 2. 观察者模式(observable)varnamebyDelegates.observable(""){prop,old,new->println("$old->$new")}// 3. 映射委托(map)classUser(valmap:Map<String,Any?>){valname:Stringbymapvalage:Intbymap}valuser=User(mapOf("name"to"Alice","age"to25))println(user.name)// "Alice"

7.在 Compose 中的完整示例

@ComposablefunCounter(){// 1. 使用 by(推荐)varcount1byremember{mutableStateOf(0)}// 2. 不使用 byvalcount2=remember{mutableStateOf(0)}Column{// 使用 count1(简洁)Button(onClick={count1++}){Text("Count1:$count1")}// 使用 count2(繁琐)Button(onClick={count2.value++}){Text("Count2:${count2.value}")}// 3. 只读状态也可以使用 byvaldoubledbyremember{derivedStateOf{count1*2}}Text("Doubled:$doubled")}}

8.重要区别总结

特性by没有by
类型看起来是基础类型(Int, String)MutableState<T>类型
读取val current = countval current = count.value
写入count = 10count.value = 10
用途UI 状态变量需要传递状态对象本身
可读性更高,像普通变量较低,显式表明是状态

9.记忆技巧

可以把by理解为:

  • “通过…来管理”:这个属性通过后面的委托对象来管理
  • “由…代理”:这个属性的读写操作由委托对象代理
  • 语法糖:让代码更简洁的语法糖

简单规则

  • 如果属性需要在 UI 中直接使用(读取/写入),用by
  • 如果属性对象本身需要作为参数传递,不用by

10.实际应用建议

// ✅ 推荐:UI 状态使用 byvartextbyremember{mutableStateOf("")}varisSelectedbyremember{mutableStateOf(false)}varcounterbyremember{mutableIntStateOf(0)}// ✅ 推荐:需要传递的对象不用 byvalscrollState=rememberScrollState()valpagerState=rememberPagerState()vallazyListState=rememberLazyListState()// 使用:LazyColumn(state=lazyListState){...}// 需要传递状态对象本身HorizontalPager(state=pagerState){...}

一句话总结by让状态变量看起来和用起来像普通变量,但背后是委托给MutableState管理,这样 Compose 能自动跟踪变化并触发重组。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/8/24 16:31:17

Compose 中的状态可变性体系

您说得非常对&#xff01;您的直觉是正确的。Compose 确实有类似 Kotlin 集合的可变/不可变概念&#xff0c;但是实现方式不同。 1. Compose 中的状态可变性体系 Kotlin 集合的类比&#xff1a; // Kotlin 集合 val immutableList: List<String> listOf("A"…

作者头像 李华
网站建设 2026/8/24 20:13:25

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

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

作者头像 李华
网站建设 2026/8/27 6:45:59

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

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

作者头像 李华
网站建设 2026/8/23 19:28:52

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

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

作者头像 李华
网站建设 2026/8/26 18:52:16

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

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

作者头像 李华
网站建设 2026/8/22 10:44:39

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

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

作者头像 李华