如何将scala泛型类型与trait匹配
这是传入DatabaseType的原始方法如何将scala泛型类型与trait匹配,scala,generics,scala-2.10,Scala,Generics,Scala 2.10,这是传入DatabaseType的原始方法 trait DatabaseComponent class Database { this: DatabaseComponent => } object Database { def apply(dbType : DatabaseType): Unit ={ val database = dbType match { case DatabaseType.H2 => new Database with H2C
trait DatabaseComponent
class Database {
this: DatabaseComponent =>
}
object Database {
def apply(dbType : DatabaseType): Unit ={
val database = dbType match {
case DatabaseType.H2 => new Database with H2Component {}
case DatabaseType.MySQL => new Database with MySQLComponent {}
case DatabaseType.PostgresSQL => new Database with PostgresSQLComponent {}
}
}
}
但是,我想传入泛型类型,并使用typeOf(T)
像在C中一样#
private void Apply(){
开关(类型(T)){
某物
}
}
我正在看这篇文章
但我仍然不确定这是在做什么
1) 对于这个val string=implicitly[ClassTag[string]]
2) 为什么T
必须是ClassTag
的子类,这里隐式地[ClassTag[T]]匹配{
3) 我应该在这里使用ClassTag还是TypeTag?<1和2有点相同的答案,您可能想了解类型类。这里的类型类是ClassTag[T]。本质上,类型类是可以“附加”的接口通过名为类型类实例的实现来访问任何类型。在Scala中,类型类的实例在隐式范围中查找,因此,虽然可以为一个类型实现多个不同的实例,但可能永远不会有多个实现(或者不明确)。如果您编写类似
def method[T : TypeClass](p1, p2, ...)
在调用方法时,您强制在作用域中拥有类型T的TypeClass实例
def method[T](p1, p2, ...)(implicit val ev: TypeClass[T]) ...
所以实际上有一个隐藏参数,可以显式地给出(!)
隐式[X]实际上是一个方法,用于获取当前作用域中存在的X类型的任何隐式值。实际上,您可以自己实现它:
def yourImplicitly[T](implicit val ev: T) : T = ev
类型类有很多应用程序,因为这是一种富有成效的抽象。您可能想了解“扩展问题”,因为类型类是FP语言扩展问题的解决方案
实际上,您可能会将DatabaseComponent本身设置为类型类
通过@uberwach部分补充答案 与C#不同,JVM具有类型擦除功能,可以在运行时擦除所有类型日期。因此在Scala中不可能使用
typeOf
。您无法在运行时创建类型T的新实例
我没有听说它被描述为扩展问题-你的意思是吗?是的,你是对的。但是,它也与扩展有关(仔细检查链接wiki文章中引用的源代码)。实际上,扩展问题可能是一个更好的术语。所以我是对的。
def yourImplicitly[T](implicit val ev: T) : T = ev