news 2026/2/11 22:26:18

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/2/10 9:52:53

Device ID 19个字节 跟 计数器 21位组成 KSN最后5个字节!

二进制转换分析&#xff1a; 00 -> 0000 000003 -> 0000 0011c0 -> 1100 000000 -> 0000 00000f -> 0000 1111 组合成 40 位二进制流&#xff1a; 00000000 00000011 11000000 00000000 00001111 按位拆分&#xff1a; 前 19 位 (Device ID): 00000000 0000…

作者头像 李华
网站建设 2026/2/10 13:09:35

新能源电动船舶物联网远程监控系统方案

行业背景在全球 “双碳” 目标纵深推进与航运业绿色转型的浪潮下&#xff0c;新能源电动船舶已成为短途高频航运场景&#xff08;货物运输、客渡交通、港口作业等&#xff09;的核心选择。但《船舶应用电池动力规范》明确要求船舶需实时监测运行状态与电池参数、实现异常报警及…

作者头像 李华
网站建设 2026/2/9 10:50:56

基于SpringBoot的图书大厦图书管理系统毕设

博主介绍&#xff1a;✌ 专注于Java,python,✌关注✌私信我✌具体的问题&#xff0c;我会尽力帮助你。 一、研究目的 本研究旨在设计并实现一个基于SpringBoot框架的图书大厦图书管理系统。该系统旨在通过整合现代信息技术与图书管理业务&#xff0c;提高图书大厦的图书管理效…

作者头像 李华
网站建设 2026/2/10 22:47:10

【收藏】AI替代枯燥工作:大模型如何改变职场和组织模式

文章探讨了将枯燥工作交给大模型的趋势&#xff0c;指出这不仅是效率提升&#xff0c;更是AI重塑工作流程和组织模式的开始。通过销售团队被AI语音系统取代、图书封面设计流程改变等案例&#xff0c;说明AI从人类不愿干的工作入手&#xff0c;最终改变工作方式和组织结构。随着…

作者头像 李华
网站建设 2026/2/10 12:55:31

为什么switch不支持long

首先最核心的原因&#xff1a;Java 设计 switch 时&#xff0c;底层是基于 int 类型实现的。 switch 的字节码指令&#xff08;比如 lookupswitch/tableswitch&#xff09;只认 int 类型&#xff0c;所有能进 switch 的类型&#xff08;byte/short/char/String&#xff09;&…

作者头像 李华