Контроль области действия Kotlin DSL на внешних неизменяемых классах (аналог @DslMarker) - PullRequest
0 голосов
/ 15 ноября 2018

У меня есть много внешних классов (сгенерированных извне; не под моим контролем), которые не поставляются с компоновщиком и которые довольно громоздки для создания. Однако, используя apply, их довольно легко построить, например,:

.
SomeOfTheObjects().apply {
  someProperty = SomeOtherComplexObject().apply {
    someOtherProperty = "..."
  }
}

Теперь мне нравится, как он работает с ресивером, но я бы хотел, чтобы я не мог установить someProperty в пределах SomeOtherComplexObject. Если бы классы были под моим контролем, было бы достаточно поместить @DslMarker в этот класс, но, поскольку они не являются, единственный другой способ, который мне пришёл в голову, это использовать also вместо того, чтобы переименовывать параметр, например:

SomeOfTheObjects().also {
  it.someProperty = SomeOtherComplexObject().also {
    it.someOtherProperty = "..."
    //it.someProperty will not work if SomeOtherComplexObject has no such property
  }
}

Несмотря на то, что он работает, в коде теперь есть тонны it., и мне было интересно, возможно ли иметь такое же поведение, как при @DslMarker.

То, что я пробовал, представляет собой смесь следующего:

@DslMarker
annotation class DemoMarker

@DemoMarker
inline fun <T> T.build(@DemoMarker builder : T.() -> Unit) = this.apply(builder)

"смесь", потому что я в конечном итоге поместил аннотацию везде, но это не имеет никакого эффекта. Если я ставлю его на уроке, он работает как положено. Я что-то пропустил, и это действительно возможно как-то? Или у кого-нибудь есть подходящий обходной путь для этого, кроме использования also?

1 Ответ

0 голосов
/ 17 января 2019

Для сторонних классов вы можете использовать аннотацию DslMarker для типов приемников, как объяснено здесь .

@DslMarker
@Target(AnnotationTarget.CLASS, AnnotationTarget.TYPE)
annotation class TestDsl

fun build1(builder: (@TestDsl DslReceiver1).() -> Unit) {}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...