Kotlin修改Protobuf重复字段遇‘val cannot be reassigned’错误的解决方法
修改Protobuf重复字段时"val cannot be reassigned"错误的解决方法
问题场景
我是Kotlin新手,在处理Protobuf重复字段修改时遇到问题。现有Protobuf消息结构如下:
message A { optional B b = 0; } message B { repeated C c = 0; } message C { optional string value = 0; }
接收A类型请求后,需要为所有未设置value字段的C类型对象设置默认值“balabala”,编写的代码如下:
fun updateValue(a: A): A{ a.b.c.forEach { if (it.value.isNullOrEmpty()) { it.apply { value = "balabala" } } } }
但运行时始终报错“val cannot be reassigned”,请问如何实现需求?
解决方案
原因分析
Protobuf生成的Kotlin类默认是不可变实例,所有字段都是val类型,无法直接修改已有实例的字段值。必须通过Protobuf提供的**Builder(构建器)**模式来创建新的可修改实例,最终生成更新后的不可变对象。
实现代码
fun updateValue(a: A): A { // 若a的b字段未设置,直接返回原对象 val originalB = a.b ?: return a // 创建B的构建器,复制原有内容 val bBuilder = originalB.toBuilder() // 遍历所有C对象,处理空value的情况 bBuilder.cList.forEachIndexed { index, c -> if (c.value.isNullOrEmpty()) { // 通过C的构建器修改value并生成新实例 val updatedC = c.toBuilder() .setValue("balabala") .build() // 替换构建器中对应位置的C对象 bBuilder.setC(index, updatedC) } } // 构建新的A实例并返回 return a.toBuilder() .setB(bBuilder.build()) .build() }
关键说明
- 每个Protobuf生成的类都自带
toBuilder()方法,用于基于现有实例创建可修改的构建器 - 对于
repeated类型的字段,无法直接修改列表中的元素,需通过构建器的setC(index, updatedC)方法替换对应位置的实例 - 最终通过构建器的
build()方法生成新的不可变实例,保证线程安全和数据一致性
内容的提问来源于stack exchange,提问作者DutchBro
相关产品推荐
相关产品推荐

