Scala中具有通用返回类型的模式匹配

时间:2018-10-25 09:47:55

标签: scala generics pattern-matching

有四种不同类型:位置,语言,技术和行业。每种类型都有一个存储库,可以返回这些类型的集合。例如位置列表。每个类型都有一个类型为String的name属性。有一个字符串列表。其中可以包含位置,语言等的名称。我想编写一个函数来查找与字符串列表的名称匹配的那些类型化的实体(位置,语言等)。我在想这样的事情:

def find[T](names: String): Set[T] = {
  val collection = T match {
    case Language => LanguageRepository.getAll
    case Location => LocationRepository.getAll
    case Teehnology => TechnologyRepository.getAll
    case Industry => IndustryRepository.getAll
  }
  // find the elements in the collection
}

这是不正确的,那么如何进行集合的查询,然后如何确定name属性在那里?

2 个答案:

答案 0 :(得分:2)

为什么不为此使用algebraic data types?它们可以用作枚举。示例:

sealed trait Property
case object LanguageProperty extends Property
case object LocationProperty extends Property
case object TechnologyProperty extends Property
case object IndustryProperty extends Property

def find(names: String, property: Property): Set[ParentClass] = {
  val collection = property match {
    case LanguageProperty => LanguageRepository.getAll
    case LocationProperty => LocationRepository.getAll
    case TechnologyProperty => TechnologyRepository.getAll
    case IndustryProperty => IndustryRepository.getAll
  }
  // find the elements in the collection
}

暗示ParentClass是您的LanguageLocationTechnologyIndustry类的父类。

答案 1 :(得分:0)

您可以传递一个隐式的ClassTag值来确定您传递的运行时类

case class Language()
case class Location()
case class Teehnology()
case class Industry()

val LANG = classOf[Language]
val LOC = classOf[Location]
val TEC = classOf[Teehnology]
val IND = classOf[Industry]

def find[Z](names: String)(implicit ct: ClassTag[Z]): Set[Z] = {
  val collection = ct.runtimeClass match {
    case LANG => Set(Language())
    case LOC => Set(Location())
    case TEC => Set(Teehnology())
    case IND => Set(Industry())
  }
  collection.asInstanceOf[Set[Z]]
}

然后

find[Language]("")
find[Industry]("")

产生

res0: Set[Language] = Set(Language())
res1: Set[Industry] = Set(Industry())