Сопоставление с образцом в Scala с универсальным типом возврата - PullRequest
0 голосов
/ 25 октября 2018

Существует четыре типа: местоположение, язык, технология и промышленность.Для каждого типа существует хранилище, которое может возвращать коллекцию этих типов.Например список мест.Каждый тип имеет свойство name с типом String.Есть список строк.который может содержать имена Locations, Languages ​​и т. д. Я хотел бы написать функцию для поиска тех типизированных сущностей (Location, Language, ...), которые соответствуют именам списка String.Я думал о чем-то вроде этого:

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 голосов
/ 25 октября 2018

Вы можете передать неявное значение 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())
0 голосов
/ 25 октября 2018

Почему бы не использовать алгебраические типы данных для этого?Они могут служить перечислениями.Пример:

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 является родительским классом ваших Language, Location, Technology и Industry классов.

...