商城首页欢迎来到中国正版软件门户

您的位置: 首页 > 文章列表 > 编程开发 > Kotlin 中如何实现类似 Java 的赋值链式语法?

Kotlin 中如何实现类似 Java 的赋值链式语法?

  发布于2026-07-07 阅读(0)

扫一扫,手机访问

在 Ja va 里,lastName = firstName = "Matroskin" 这样的写法是合法的——因为赋值操作符 = 本身是表达式,会返回被赋的值,自然就能串起来。但 Kotlin 的设计者显然不想让赋值产生什么“意外副作用”,于是明确把赋值变成了语句(statement),没有返回值。所以你要是直接写 firstName = lastName = "Matroskin",编译期就会甩给你一句:“Assignments are not expressions, and only expressions are allowed in this context。”

不过话说回来,虽然不能照搬 Ja va 的链式赋语法,但 Kotlin 生态里从来不缺优雅的等效方案。下面这几种方式,既安全又符合 Kotlin 风格——你挑着用就好。

✅ 最推荐:用作用域函数(idiomatic Kotlin)

作用域函数是 Kotlin 的“招牌武器”之一。拿 let 来举例:把要赋的值丢进 let 的 lambda 里,然后一次性给多个属性赋值。看起来就像这样:

class Cat {
    var firstName: String = ""
    var lastName: String = ""

    constructor() : this("") {
        "Matroskin".let { name ->
            firstName = name
            lastName = name
        }
    }
    // 如果构造逻辑简单,也可以直接:
    constructor(name: String) {
        firstName = name
        lastName = name
    }
}

let 的好处很明显:第一,避免了重复字面量;第二,天然支持空安全——把 "Matroskin" 换成 someString?.let { ... } 就行,完全无缝对接。

✅ 另一种:构造器参数 + init 块

如果属性需要延迟初始化,或者牵涉到更复杂的逻辑,不妨用主构造参数配合 init 块:

class Cat(name: String) {
    var firstName: String = name
    var lastName: String = "" // 先占个位

    init {
        lastName = firstName // 复用已经初始化的值
    }
}

这种写法的语义非常直白,没有额外开销,而且对 val 属性也友好(init 块里只能赋值一次,符合 val 的约束)。

⚠️ 不太推荐:用自定义 infix 函数“模拟”链式赋值

技术上确实可以用 infix 扩展玩出链式效果,但说实话——这已经踩到 Kotlin 设计哲学的底线了。看看代码:

infix fun  T.`=`(prop: KMutableProperty): T {
    prop.setter.call(prop, this)
    return this
}

// 使用时需要先声明可变属性:
var firstName = ""
var lastName = ""
"Matroskin" `=` ::lastName `=` ::firstName // ❌ 编译失败:未初始化

问题一大把:属性必须提前给默认值(不然过不了空安全检查);::propertyName 引用的是实例属性,只能在对象创建后使用,没法在构造器里直接初始化;val 属性压根不支持(因为没有 setter);代码可读性差,调试时很难追踪副作用。

所以这个技巧,看看就好,就当了解 Kotlin 的底层机制——千万别往生产代码里放

✅ 总结一下:到底怎么选?

场景推荐方式
简单统一赋值(比如构造时把同一个值赋给多个属性)主构造参数 + 多属性直接赋值(firstName = name; lastName = name
需要条件判断或复杂逻辑let / also 作用域函数
属性依赖其他属性的初始化结果init 块或 by lazy(针对 val
追求极致简洁且希望复用封装成工厂函数,或放在伴生对象 companion object 里的 create() 方法

说到底,Kotlin 把赋值设计成语句而非表达式,不是缺陷,而是刻意的取舍——它拒绝隐式副作用,让代码的确定性更高。只要习惯了 Kotlin 原生的那套工具(作用域函数、init 块、by lazy 等),你会发现写出来的代码既安全又清晰,完全不输 Ja va 的链式赋值,甚至更好读。

本文转载于:https://www.php.cn/faq/2433237.html 如有侵犯,请联系zhengruancom@outlook.com删除。
免责声明:正软商城发布此文仅为传递信息,不代表正软商城认同其观点或证实其描述。

热门关注