アレッ*_*ックス 9 scala type-erasure type-parameter type-members
这很好用
class MyClass[T<: Actor: ClassTag] extends Actor {
//....
}
Run Code Online (Sandbox Code Playgroud)
但这不是由于错误 No ClassTag available for MyClass.this.T
class MyClass extends Actor {
type T<: Actor
//...
}
Run Code Online (Sandbox Code Playgroud)
即使执行以下操作:
class MyClass extends Actor {
type T<: Actor: ClassTag //this doesn't even compile
//...
}
Run Code Online (Sandbox Code Playgroud)
我如何使用摘要type并摆脱错误?
class M[A <: B: C]
Run Code Online (Sandbox Code Playgroud)
是的缩写
class M[A <: B](implicit c: C[A])
Run Code Online (Sandbox Code Playgroud)
因此,如果您转移A到抽象类型成员,则必须编写类似的内容
abstract class M {
type A <: B
implicit protected def c: C[A]
}
Run Code Online (Sandbox Code Playgroud)
并要求任何人实施M提供这样的价值 c.如果你想要M非抽象,你必须要求一个类型的构造函数值参数C[A],这反过来意味着类型A必须是构造函数类型参数...
编辑以回答注释:符号A : C 定义为扩展为类型的隐式值参数C[A].有C一个称为上下文绑定,可以理解为要求类型C[_]的类型A.如果实现 M,则不需要重复implicit修饰符.为什么会这样?让我举个例子,使用一个众所周知的类型Ordering:
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
}
}
Run Code Online (Sandbox Code Playgroud)
如果你删除implicit,你将不得不改变对通话xs.min和xs.max需要一个隐含的Ordering.
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)
Run Code Online (Sandbox Code Playgroud)
此处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]
}
Run Code Online (Sandbox Code Playgroud)
如果您的子类再次是通用的,则需要传递提供类标记的责任:
class GenericClass[A1](implicit val tag: reflect.ClassTag[A1]) {
type A = A1
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
2879 次 |
| 最近记录: |