可变属性上的Kotlin扩展函数

时间:2016-07-11 13:28:14

标签: properties kotlin kotlin-extension

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

我的目标是制作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对象上使用。

是否可以这样做?

2 个答案:

答案 0 :(得分: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
}

答案 1 :(得分: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)

使用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对象的引用。这个解决方案适用于可变对象,但它不适合存储不可变对象的属性。