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

Kotlin使用apply时属性与函数参数同名如何正确赋值

Kotlin apply作用域同名属性赋值报错解决方案

问题复现

触发报错的代码如下:

data class Foo(
  var aaa: String,
  var bbb: String
)

fun bar(aaa: String) {
  Foo().apply {
    aaa = aaa // 该行IDE抛出错误
    bbb = "bbb"
  }
}

IDE抛出错误提示:Val cannot be reassigned。

错误原因

这个报错和属性修饰符无关,核心是Kotlin的标识符解析规则:

  • 函数参数属于当前函数的局部变量,解析优先级高于作用域函数的隐式接收者成员属性
  • apply块内未加前缀的同名标识符aaa,会被优先识别为外层bar函数的入参aaa,而非Foo实例的属性
  • Kotlin函数参数默认是val修饰的不可变值,不允许重新赋值,因此触发报错

补充说明:示例中Foo类的属性已经修正为var修饰,如果属性本身用val修饰,无论哪种写法都无法在apply作用域内修改该属性。

可行解决方案

  • 方案1:显式指定接收者指向实例属性(最常用)
    给赋值目标加上接收者前缀,明确告诉编译器等号左侧是Foo实例的属性,等号右侧自动解析为外层函数参数,无歧义:
    fun bar(aaa: String) {
      Foo().apply {
        this.aaa = aaa
        bbb = "bbb"
      }
    }
    
    如果存在多层嵌套的作用域函数,可以使用带标签的this明确指定接收者,避免嵌套场景下的解析错误:
    fun bar(aaa: String) {
      Foo().apply {
        this@apply.aaa = aaa
        bbb = "bbb"
      }
    }
    
  • 方案2:重命名外层参数避免同名冲突
    直接给函数入参设置和类属性不重名的命名,从根源上消除解析歧义,代码可读性更高:
    fun bar(aaaValue: String) {
      Foo().apply {
        aaa = aaaValue
        bbb = "bbb"
      }
    }
    

内容的提问来源于stack exchange,提问作者eth4io

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.26 11:06:19