Проверка типа времени компиляции при добавлении элементов элемента в список - PullRequest
0 голосов
/ 30 марта 2020

Возможно ли реализовать его во время компиляции, используя Scala?

Вариант использования:

  • Пользователь API пытается создать список Thing с.
  • Как только пользователь добавляет подкласс ComplexThing, ему не разрешается добавлять что-либо еще

Это легко проверить во время выполнения, и есть ли решения для его реализации во время компиляции ? Цель состоит в том, чтобы сделать IDE для выделения ошибки компиляции.


trait Thing

trait SimpleThing extends Thing

trait ComplexThing extends Thing

sealed case class DummySimpleThing() extends SimpleThing

sealed case class InstanceOfComplexThing() extends ComplexThing

class ThingRepository {
  private val buffer = new ListBuffer[Thing]()

  def addThing(thing: Thing): ThingRepository = {
    buffer += thing
    this
  }
}

object TestThingRepository {

  def testAddThings() = {
    new ThingRepository()
      .addThing(DummySimpleThing())
      .addThing(DummySimpleThing()) // it's ok to add SimpleThing after SimpleThing
      .addThing(InstanceOfComplexThing()) // it's ok to add ComplexThing after SimpleThing

      .addThing(DummySimpleThing()) // Not allowed to add anything after ComplexThing, how can I get compile time error here?
      .addThing(InstanceOfComplexThing()) // Not allowed anything after ComplexThing, how can I get compile time error here?
  }
}

1 Ответ

2 голосов
/ 30 марта 2020

Вы не можете сделать это с изменяемым репозиторием, потому что вы не можете изменить сигнатуру класса, как только он определен.

Это было бы возможно сделать, если бы addThing возвратил новый репозиторий, потому что добавление ComplexThing может вернуть хранилище без метода addThing, а добавление SimpleThing возвращает хранилище с методом addThing.

case class StaticThingRepository(buffer: List[Thing])

class ThingRepository private(buffer: List[Thing]) {  
  def addThing(thing: Thing): ThingRepository =
    new ThingRepository(buffer :+ thing)

  def addThing(thing: ComplexThing): StaticThingRepository =
    StaticThingRepository(buffer :+ thing)
}

object ThingRepository {
  def apply() = new ThingRepository(Nil)
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...