Я не уверен, что название описывает мой вопрос лучше всего, но давайте сделаем это.Общие аргументы метода в scala
У меня есть приложение для выполнения фоновых заданий, которое напоминает простую обработку конвейера. Есть Command
объектов, которые делают некоторые вычисления и возвращают OUTPUT
и Worker
, которые получают OUTPUT
в качестве входных данных и может вернуться Result
объектная модель выглядит примерно так:
type OUTPUT <: AnyRef
trait Command[OUTPUT] {
def doSomething(): OUTPUT
}
sealed trait Worker[IN <: AnyRef, OUT <: Result] {
def work(input: IN): OUT
}
case class WorkA() extends Worker[String, LongResult] {
override def work(input: String): LongResult = LongResult(Long.MaxValue)
}
case class WorkB() extends Worker[Long, StringResult] {
override def work(input: Long): StringResult = StringResult(input.toString)
}
Есть несколько проблем с этим подходом:
При сопоставлении коллекции Worker
я не могу убедиться, что рабочий принимает тот же OUTPUT
в качестве входных данных.
Если я не буду отображения списка Command
, код не компилируется из-за типа стирания - это ожидает _$1
, но получает Long
или в String
(все, что было ранее принято в качестве OUTPUT
)
val workers = List(
new WorkA(),
new WorkB()
)
val aSimpleCommand = new Command[Long] {
override def doSomething() = 123123123L
}
// Obviously this doesn't compile.
workers.map(worker => worker.work(aSimpleCommand.doSomething()))
Я ищу правильный механизм Scala, чтобы запретить это во время компиляции. Как я могу отобразить только на работнике, которые фактически поддерживают OUTPUT
- и в этом случае, только WorkB
Здесь вы не можете понять. В списке «worker» есть 1 работник, который принимает «String» и другой рабочий, который принимает «Long». 'aSimpleCommand.doSomething' возвращает' Long', но используя 'map', вы пытаетесь передать его' WorkA', который хочет 'String'. Конечно, он не может скомпилироваться. – Kolmar
Точно @ Kolmar. Я ищу правильный механизм Scala, чтобы запретить это во время компиляции. Как я могу отображать ТОЛЬКО на «Рабочем», который действительно поддерживает «OUTPUT» - и в этом случае только «WorkB» – yarinbenado
Я думаю, что точка зрения Колмара заключается в том, что это уже не разрешено во время компиляции - я предполагаю, что вы имеете в виду, как это сделать вы запрещаете его в _runtime_ (т. е. скомпилируйте его с радостью, но отфильтровывайте ненадлежащих сотрудников во время выполнения)? – Shadowlands