可变 属性 上的 Kotlin 扩展函数

Kotlin extension function on mutable property

我正在尝试在可变 属性 上设置扩展函数,以便我可以在扩展函数中重新分配 属性。我想知道这是否可能。

我的目标是制作 Date 扩展以便于访问。例如:

fun Date.addDays(nrOfDays: Int): Date {
    val cal = Calendar.getInstance()
    cal.time = this
    cal.add(Calendar.DAY_OF_YEAR, nrOfDays)
    return cal.time
}

此函数使用 Calendar 对象向日期添加天数。问题是每次我都必须 return 一个新日期,每次使用此功能时都可能会混淆重新分配。

我尝试过的:

fun KMutableProperty0<Date>.addDays(nrOfDays: Int) {
    val cal = Calendar.getInstance()
    cal.time = this.get()
    cal.add(Calendar.DAY_OF_YEAR, nrOfDays)
    this.set(cal.time)
}

不幸的是,这不能用于 Date 对象。

可以这样做吗?

遗憾的是,您无法在成员 属性 上定义扩展并在 Kotlin 1.0.3 中流畅地调用它。

您的扩展可以重写为这样工作:

fun <T> KMutableProperty1<T, Date>.addDays(receiver: T, nrOfDays: Int) {
    val cal = Calendar.getInstance()
    cal.time = this.get(receiver)
    cal.add(Calendar.DAY_OF_YEAR, nrOfDays)
    this.set(receiver, cal.time)
}

使用以下用法:

class C(var date: Date) { ... }
val c = C(someDate())

C::date.addDays(c, 123)

使用 bound callable references (likely supported in Kotlin 1.1) 可以使用以下语法:

c::date.addDays(123)

正如@MarcinKoziński 所建议的,您还可以在不重新分配 属性:

的情况下改变 Date 对象
fun Date.addDays(nrOfDays: Int) {
    val cal = Calendar.getInstance()
    cal.time = this
    cal.add(Calendar.DAY_OF_YEAR, nrOfDays)
    this.time = cal.timeInMillis
}

使用情况:

class C(var date: Date)
val c = C(someDate())

c.date.addDays(123)

使用此解决方案,您必须控制对已变异的 Date 对象的引用。此解决方案适用于可变对象,但不适用于 属性 存储不可变对象。

无需返回新的 Date 并尝试更新您的 属性,您只需改变您的 属性 已经拥有的 Date

fun Date.addDays(nrOfDays: Int) {
    val cal = Calendar.getInstance()
    cal.time = this
    cal.add(Calendar.DAY_OF_YEAR, nrOfDays)
    this.time = cal.timeInMillis
}