Функция vetoable

Функция vetoable создает делегат свойства, который позволяет перехватывать попытки изменения значения и отклонять их при необходимости. В первый параметр передается начальное значение свойства, а во второй параметр - лямбда-функция, которая принимает старое значение, новое значение и возвращает Boolean. Если функция возвращает true, изменение применяется, если false - изменение отклоняется.

Импорт

kotlinimport kotlin.properties.Delegates.vetoable

Синтаксис

kotlinfun <T> vetoable(
  initialValue: T, 
  onChange: (property: KProperty<*>, oldValue: T, newValue: T) -> Boolean
): ReadWriteProperty<Any?, T>
kotlinfun <T> vetoable(
  initialValue: T, 
  onChange: (oldValue: T, newValue: T) -> Boolean
): ReadWriteProperty<Any?, T>

Пример

Создадим свойство, которое принимает только положительные числа:

kotlinvar positiveNumber: Int by vetoable(0) { old, new ->
  if (new > 0) {
    true
  } else {
    println("Rejected: $new is not positive")
    false
  }
}

positiveNumber = 10
println(positiveNumber)

positiveNumber = -5
println(positiveNumber)

Результат выполнения кода:

kotlinInt 10
Rejected: -5 is not positive
Int 10

Пример

Создадим свойство для возраста, которое не позволяет установить значение меньше 0 или больше 150:

kotlinvar age: Int by vetoable(18) { old, new ->
  if (new in 0..150) {
    true
  } else {
    println("Rejected: $new is not a valid age")
    false
  }
}

age = 25
println(age)

age = 200
println(age)

Результат выполнения кода:

kotlinInt 25
Rejected: 200 is not a valid age
Int 25

Пример

Использование полной сигнатуры с параметром property:

kotlinvar userName: String by vetoable("") { prop, old, new ->
  if (new.length >= 3) {
    println("Property ${prop.name} changed from '$old' to '$new'")
    true
  } else {
    println("Rejected: username must be at least 3 characters")
    false
  }
}

userName = "John"
println(userName)

userName = "Ab"
println(userName)

Результат выполнения кода:

kotlinProperty userName changed from '' to 'John'
String "John"
Rejected: username must be at least 3 characters
String "John"

Пример

Создадим свойство для email с проверкой формата:

kotlinvar email: String by vetoable("") { old, new ->
  if (new.contains("@") && new.contains(".")) {
    true
  } else {
    println("Rejected: '$new' is not a valid email")
    false
  }
}

email = "test@example.com"
println(email)

email = "invalid-email"
println(email)

Результат выполнения кода:

kotlinString "test@example.com"
Rejected: 'invalid-email' is not a valid email
String "test@example.com"

Смотрите также

  • функцию observable,
    которая отслеживает изменения свойств без возможности отмены
  • класс Lazy,
    который обеспечивает ленивую инициализацию свойств
  • интерфейс MutableList,
    который представляет изменяемую коллекцию элементов
  • класс Pair,
    который представляет пару значений