我正在寻找一种从以下示例中S
的调用中删除类型参数的方法:apply
object Attribute {
trait Int [S] extends Attribute[S]
trait Boolean[S] extends Attribute[S] // etc.
}
sealed trait Attribute[S]
trait Attributes[S] {
protected def get(key: String): Option[Attribute[S]]
def apply[A <: Attribute[S]](key: String)
(implicit tag: reflect.ClassTag[A]): Option[A] =
get(key) match {
case Some(attr: A) => Some(attr)
case _ => None
}
}
使用上述定义,测试用例将是:
trait Test[S] {
def map: Attributes[S]
map[Attribute.Int[S]]("foo")
}
我想要做的是修改apply
定义以允许以下内容:
trait Test2[S] {
def map: Attributes[S]
map[Attribute.Int]("foo") // use partially applied attribute type
}
编辑:所以跟进 Marius 的建议和评论,为什么以下内容仍然会产生擦除警告:
import reflect.runtime.universe._
trait Attributes[S] {
protected def get(key: String): Option[Attribute[S]]
def apply[A[x] <: Attribute[x]](key: String)
(implicit tag: TypeTag[A[S]]): Option[A[S]] =
get(key) match {
case Some(attr: A[S]) => Some(attr)
case _ => None
}
}
对我来说,这显然没有意义。一方面,我有完整的类型标签A[S]
可供使用。另一方面,它甚至应该在它不存在的情况下完全工作,因为它Attribute
是不变的S
,所以如果我得到一个Option[Attribute[S]]
,并且我匹配Some(attr: A[x])
,唯一的可能性就是x == S
。
编辑2:解决方案的条件是Attribute
特征的形状没有改变,例如不将类型构造函数参数移动S
到成员字段。