Предположим, что мы имеем общий класс Container
:
case class Container[+A](value: A)
Затем мы хотим сопоставить шаблон Container
с Double
и Container
Any
:
val double = Container(3.3)
var container: Container[Any] = double
Для этого мы обычно пишем:
container match {
case c: Container[String] => println(c.value.toUpperCase)
case c: Container[Double] => println(math.sqrt(c.value))
case _ => println("_")
}
Однако компилятор дает два предупреждения: по одному для каждого из первых двух случаев. Например, первое предупреждение говорит: "Аргумент типа non-variable String в шаблоне типа Container [String] не отмечен, поскольку он устраняется стиранием". Из-за стирания во время выполнения невозможно различать различные типы контейнеров, и первый улов будет согласован. Как следствие, контейнер типа Container[Double]
будет сопоставляться первым случаем, который ловит Container[String]
объекты, поэтому метод toUpperCase
будет вызываться в Double
, а a java.lang.ClassCastException
будет выбрано.
Как сопоставить параметр Container
, параметризованный определенным типом?