这是传入DatabaseType的原始方法。
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 {}
}
}
}
但是,我希望传递泛型类型并使用{C}
中的typeOf(T)
private void Apply<T>(){
switch(typeOf(T)){
Something
}
}
我正在看这篇文章How to match scala generic type?
但我仍然不确定这是做什么的。
1)与val string = implicitly[ClassTag[String]]
2)为什么T
必须是ClassTag
的子类implicitly[ClassTag[T]] match {
3)我应该在这里使用ClassTag还是TypeTag?
答案 0 :(得分:1)
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
类型类有很多应用程序,因为这是一种富有成效的抽象。您可能想要了解&#34;扩展问题&#34;,因为类型类是FP语言扩展问题的解决方案。
实际上,您可能会将DatabaseComponent本身设为类型类。
答案 1 :(得分:0)
部分补充@uberwach的答案
与C#不同,JVM具有类型擦除功能,可在运行时删除所有类型的日期。所以在Scala中不可能typeOf
。您无法在运行时创建类型为T的新实例。