Scala: Тип аннотации параметра сбрасывает ClassTag в Option и портит сопоставление типов - PullRequest
0 голосов
/ 27 июня 2019

У меня есть черта с параметром типа.Внутри этой черты я хочу определить метод, который проверяет, соответствует ли объект параметру типа.Пока это работает, так как я хочу, чтобы это работало:

import scala.reflect.ClassTag
trait MyTrait[A <: AnyVal]{
    def hasType(x: AnyVal)(implicit tag: ClassTag[A]) = x match {
        case _: A => true
        case _    => false
    }
}

object MyObject extends MyTrait[Int]

println(MyObject.hasType(5))   // returns true
println(MyObject.hasType(5.0)) // returns false

Проблема возникает, когда MyTrait -объекты являются параметрами класса, как здесь:

class WrappingClass(myObjects: Seq[MyTrait[_]]) {
    def hasType(x: AnyVal) = {
        myObjects.foreach(
            mo => println(mo.hasType(x))
        )
    }
}

object AnotherObject extends MyTrait[Double]
val wrappingObject = new WrappingClass(Seq(MyObject, AnotherObject))
wrappingObject.hasType(5)   // prints only "true"
wrappingObject.hasType(5.0) // prints only "true"

Итакв основном аннотация типа Seq[MyTrait[_]] параметра превращает мой ClassTag в общий объект и приводит к совпадению типов.Я действительно хотел бы избежать написания метода hasType в каждом объекте, который наследуется от черты.

1 Ответ

2 голосов
/ 27 июня 2019

Вам необходимо использовать класс с ограничением контекста ClassTag (так как эти границы не используются в чертах).Если вы замените MyTrait на:

abstract class MyTrait[A <: AnyVal: ClassTag] {
    def hasType(x: AnyVal) = x match {
      case _: A => true
      case _ => false
    }
}

, все будет работать так, как вы ожидаете

...