You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.15 00:10:29