Scala элемент класса case, параметризованный с подстановочными типами, не определяет границы типа при вызове - PullRequest
0 голосов
/ 16 января 2020

Я искал в Интернете, но не получил полезного результата. Может быть, это глупо, но я пытаюсь заставить это работать. Описание моего вопроса может быть показано в следующем примере:

trait EnumType
class MyEnum extends EnumType

trait Coherence[S <: EnumType] {
    def printS(s: S): Unit
}

class MyCoherence extends Coherence[EnumType] {
    override def printS(s: EnumType): Unit = println("printS in MyCoherence")
}

case class MyCaseClass(coh: Coherence[_ <: EnumType])

object HelloWorld {
   def main(args: Array[String]) {
       val myCoh = new MyCoherence
       val m = MyCaseClass(myCoh)
       val myEnum = new MyEnum

       myCoh.printS(myEnum)
       m.coh.printS(myEnum) // >>> problematic line 21
      println("Hello, world!")
   }
}

Как видите, у меня есть класс case MyCaseClass, который принимает в качестве параметра экземпляр Coherence[_ <: EnumType].

Этот экземпляр имеет простой printS(), который печатает некоторое сообщение.

В main, когда я пытаюсь вызвать printS из m.coh, компилятор выдает следующую ошибку:

$scalac *.scala
HelloWorld.scala:21: error: type mismatch;
 found   : myEnum.type (with underlying type MyEnum)
 required: _$1
       m.coh.printS(myEnum)
                    ^
one error found

Кажется, что граница типа coh стирается, когда я выполняю m.coh.printS (_$1 вместо _$1 <: EnumType).

Интересно, что-то мне не хватает используя printS таким образом? Спасибо

1 Ответ

0 голосов
/ 16 января 2020

Граница типа не стирается, просто не печатается в этой ситуации. Проблема в том, что m.coh может быть Coherence[SomeOtherEnum]:

class SomeOtherEnum extends EnumType
class OtherCoherence extends Coherence[SomeOtherEnum] {
    override def printS(s: SomeOtherEnum): Unit = ???
}

val m = MyCaseClass(new OtherCoherence)

Поскольку этот m и ваш имеют одинаковый тип, m.coh.printS(myEnum) должен проверять тип в обоих случаях или ни в одном, и он, очевидно, не может работать здесь: он вызывает OtherCoherence.printS(), который принимает только SomeOtherEnum.

. Вы можете заставить его скомпилироваться, приведя m.coh:

m.coh.asInstanceOf[Coherence[EnumType]].printS(myEnum)

Но это небезопасно из-за к вышесказанному: если m.coh является MyCoherence, оно будет работать; если m.coh является OtherCoherence, он в конечном итоге попытается привести myEnum к SomeOtherEnum и выдать исключение.

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