Как сделать поле обязательным в kotlin DSL строителей - PullRequest
0 голосов
/ 06 декабря 2018

В Kotlin при создании пользовательского DSL, каков наилучший способ принудительно заполнить обязательные поля внутри функций расширения компоновщика во время компиляции.Например:

person {
    name = "John Doe" // this field needs to be set always, or compile error
    age = 25
}

Один из способов заставить это установить значение в параметре функции вместо тела функции расширения.

person(name = "John Doe") {
    age = 25
}

, но это делает его немного более нечитаемымесли есть еще обязательные поля.

Есть ли другой способ?

1 Ответ

0 голосов
/ 02 февраля 2019

Проще, выбросить исключение, если оно не определено в вашем DLS после блока

fun person(block: (Person) -> Unit): Person {
val p = Person()
block(p)
if (p.name == null) {
  // throw some exception
}
return p
}

Или если вы хотите применить его во время сборки, просто сделайте так, чтобы оно возвращало что-то бесполезное во внешний блок, если нетопределены, как ноль.

fun person(block: (Person) -> Unit): Person? {
val p = Person()
block(p)
if (p.name == null) {
  return null
}
return p
}

Я предполагаю, что вы ушли этот пример , так что, возможно, адрес будет лучшим примером:

fun Person.address(block: Address.() -> Unit) {
// city is required
var tempAddress = Address().apply(block)
if (tempAddress.city == null) {
   // throw here
}
}

Но чтоесли мы хотим убедиться, что все определено, но также хотим, чтобы вы делали это в любом порядке и во время компиляции.Просто, есть два типа!

data class Person(var name: String = null,
              var age: Int = null,
              var address: Address = null)
data class PersonBuilder(var name: String? = null,
              var age: Int? = null,
              var address: Address? = null)
fun person(block: (PersonBuilder) -> Unit): Person {
    val pb = PersonBuilder()
    block(p)
    val p = Person(pb.name, pb.age, pb.address)
    return p
}

Таким образом, вы получаете нестрогий тип для сборки, но он лучше будет нулевым к концу.Это был забавный вопрос, спасибо.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...