Scala中返回类型的分派
假设我有以下案例类:Scala中返回类型的分派,scala,Scala,假设我有以下案例类: case class Category(name: String) case class Record(price: Double, description: String, category: Category) case class Sale(price: Double, qty: Int, dateOfSale: Date, category: Category) 我想调用一个方法,根据类别返回Sale或Record列表。唯一的区别是返回类型。因此,我想要的不是
case class Category(name: String)
case class Record(price: Double, description: String, category: Category)
case class Sale(price: Double, qty: Int, dateOfSale: Date, category: Category)
我想调用一个方法,根据类别返回Sale
或Record
列表。唯一的区别是返回类型。因此,我想要的不是findSalesByCategory
和findRecordsByCategory
,而是:
def findByCategory[T](category: Category): List[T] = classOf[T] match {
case c if c == classOf[Sale] => findRecordsByCategory(category)
case c if c == classOf[Record] => findSalesByCategory(category)
}
显然,这在以下情况下会失败:
error: class type required but T found
def findByCategory[T](category: Category): List[T] = classOf[T] match {
^
有没有可行的方法?您可以使用类型标签:
import scala.reflect.runtime.universe._
def findByCategory[T: TypeTag](category: Category): List[T] = {
typeOf[T] match {
case t if t =:= typeOf[Sale] => findSalesByCategory(category)
case t if t =:= typeOf[Record] => findRecordsByCategory(category)
}
}
由于您的类别不是通用的,
ClassTag
也可以满足以下要求:
import scala.reflect.{ClassTag, classTag}
def findByCategory[T: ClassTag](category: Category): List[T] = {
classTag[T] match {
case c if c == classTag[Sale] => findSalesByCategory(category)
case c if c == classTag[Record] => findRecordByCategory(category)
}
}
当您要匹配的T
的子类型未参数化时,这将起作用;在这种情况下,您必须使用TypeTag
s
有一种方法可以稍微简化匹配。您可以将ClassTag
s或Class
es保存到val
中,并在其上进行匹配:
import scala.reflect.{ClassTag, classTag}
val saleClass = classOf[Sale]
val recordClass = classOf[Record]
def findByCategory[T: ClassTag](category: Category): List[T] = {
classTag[T].runtimeClass match {
case `saleClass` => findSalesByCategory(category)
case `recordClass` => findRecordByCategory(category)
}
}
它不起作用-
TypeTag#tpe
返回Type
的实例,但是classOf
返回Class[\u]
,它们是不同的。您可以在Scala REPL中轻松地检查它。您可能还应该编写typeOf[Sale]
,而不是typeOf(Sale)
——它是一个类型参数。@Vladimitavevev yes。我在我的编辑器里是正确的,在这里输入错误。谢谢。您可以发布findSalesByCategory
和findRecordsByCategory
的声明吗?显然的def findRecordsByCategory(c:Category):List[Record]=??
和def findSalesByCategory(c:Category):List[Sale]=??
似乎没有编译。这是类型类的一个很好的用例。