2

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

我的目标是制作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对象将天数添加到日期。问题是每次我必须返回一个新日期,每次使用此功能时重新分配可能会令人困惑。

我试过的:

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对象。

是否有可能做到这一点?

4

2 回答 2

3

而不是返回一个新的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
}
于 2016-07-11T14:13:05.213 回答
1

不幸的是,您无法在成员属性上定义扩展并在 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)

使用绑定的可调用引用(可能在 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变异对象的引用。此解决方案适用于可变对象,但不适用于存储不可变对象的属性。

于 2016-07-11T13:53:24.533 回答