Scala 没有可用于MyClass的类标记。此.T用于抽象类型
这很有效Scala 没有可用于MyClass的类标记。此.T用于抽象类型,scala,type-erasure,type-parameter,type-members,Scala,Type Erasure,Type Parameter,Type Members,这很有效 class MyClass[T<: Actor: ClassTag] extends Actor { //.... } 即使在以下情况下: class MyClass extends Actor { type T<: Actor: ClassTag //this doesn't even compile //... } 类MyClass扩展了Actor{ T型 并要求实现M的任何人提供这样一个值c。如果希望M非抽象,则必须要求类型为c[a]的构造函数值参数,
class MyClass[T<: Actor: ClassTag] extends Actor {
//....
}
即使在以下情况下:
class MyClass extends Actor {
type T<: Actor: ClassTag //this doesn't even compile
//...
}
类MyClass扩展了Actor{
T型
并要求实现M
的任何人提供这样一个值c
。如果希望M
非抽象,则必须要求类型为c[a]
的构造函数值参数,这反过来意味着类型a
必须是构造函数类型参数
Edit回答注释:符号A:C
被定义为扩展为C[A]
类型的隐式值参数。其中C
被称为上下文绑定,可以理解为请求类型类C[\ux]
用于类型A
。如果实现M
,则无需重复隐式
修饰符。为什么会出现此修饰符?让我给您一个使用著名类型类排序
的示例:
abstract class Foo {
type A
implicit protected def ord: Ordering[A]
protected def seq: Seq[A]
def range: (A, A) = {
val xs = seq
xs.min -> xs.max
}
}
如果删除了implicit
,则必须将需要隐式排序的调用更改为xs.min
和xs.max
object Bar extends Foo {
type A = Int
val seq = List(8, 34, 5, 21, 3, 13)
val ord = Ordering.Int // don't need to repeat `implicit`
}
Bar.range // (3, 34)
这里,Bar
显示了如何提供隐式值参数。这与ClassTag
相同:
trait MyClass {
type A
implicit def tag: reflect.ClassTag[A]
}
object StringClass extends MyClass {
type A = String
// type String is statically known, thus compiler gives us this:
val tag = reflect.classTag[String]
}
如果您的子类再次是泛型的,则需要将提供类标记的责任转交给:
class GenericClass[A1](implicit val tag: reflect.ClassTag[A1]) {
type A = A1
}
有趣的是,我对它进行了一些研究,产生了两个问题:1)为什么方法c
在M
中是隐式的:?非隐式的方法不是等同于使用参数化类型的前两个版本吗?2)在ClassTag
的特殊情况下,不需要构造函数值(我将其替换为类中的override val c=classTag[…]
)。这通常不可能吗?我如何在子类中提供c:ClassTag
的实现?它应该是什么样子?似乎在object StringClass extensed MyClass
-type A=String
和val tag=reflect.ClassTag[String
]中存在冗余重复?我可以避免这种情况吗?你能给我举个例子吗?如果你想要M非抽象的,你必须需要一个C[a]类型的构造函数值参数,这反过来意味着a类型必须是构造函数类型参数吗?@Alex你或者静态地知道类型a
(示例StringClass
),否则它将保持泛型。然后,任何具体类都需要通过构造函数获取class标记(例如GenericClass
),因此,您或多或少会在离开的地方结束。关于您的第一条注释:类型参数在运行时被删除,这就是为什么您首先有标记,所以它们不是多余的。但是,如果您不使用数组,您将非常少需要它们。
abstract class Foo {
type A
implicit protected def ord: Ordering[A]
protected def seq: Seq[A]
def range: (A, A) = {
val xs = seq
xs.min -> xs.max
}
}
object Bar extends Foo {
type A = Int
val seq = List(8, 34, 5, 21, 3, 13)
val ord = Ordering.Int // don't need to repeat `implicit`
}
Bar.range // (3, 34)
trait MyClass {
type A
implicit def tag: reflect.ClassTag[A]
}
object StringClass extends MyClass {
type A = String
// type String is statically known, thus compiler gives us this:
val tag = reflect.classTag[String]
}
class GenericClass[A1](implicit val tag: reflect.ClassTag[A1]) {
type A = A1
}