Функция расширения Котлина на непостоянном свойстве
Я пытаюсь установить функцию расширения для изменяемого свойства, чтобы я мог переназначить свойство в функции расширения. Я хотел знать, было ли это возможно.
Мои цели - сделать 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 ответа
К сожалению, вы не можете определить расширение для свойства члена и свободно вызывать его в 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
объект, который мутировал. Это решение хорошо работает с изменяемыми объектами, хотя оно не подходит для свойств, хранящих неизменяемые объекты.
Вместо возвращения нового 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
}