首页 文章

Kotlin扩展函数的可变属性

提问于
浏览
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 对象 .

是否有可能做到这一点?

2 回答

  • 3

    不幸的是,您无法在成员属性上定义扩展并在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 对象的引用 . 这个解决方案适用于可变对象,但它不适合存储不可变对象的属性 .

  • 1

    您可以改变属性已经存在的 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
    }
    

相关问题