У меня есть общая карта со значениями, некоторые из которых могут быть в свою очередь списками значений. Я пытаюсь обработать заданный ключ и преобразовать результаты к типу ожидаемого внешнего вызывающего абонента, например:Специализация методов Scala для определенных тегов
// A map with some values being other collections.
val map: Map[String, Any] = Map("foo" -> 1, "bar" -> Seq('a', 'b'. 'a'))
// A generic method with a "specialization" for collections (pseudocode)
def cast[T](key: String) = map.get(key).map(_.asInstanceOf[T])
def cast[C <: Iterable[T]](key: String) = map.get(key).map(list => list.to[C].map(_.asIntanceOf[T]))
// Expected usage
cast[Int]("foo") // Should return 1:Int
cast[Set[Char]]("bar") // Should return Set[Char]('a', 'b')
Это, чтобы показать, что я хотел бы сделать, но это не работает. Ошибка компилятора (правильно, около 2 возможных совпадений). Я также попытался сделать это единственной функцией с каким-то совпадением шаблонов в типе, но безрезультатно.
Я читал на @specialized, TypeTag, CanBuildFrom и других функциях scala, но мне не удалось найти простой способ собрать все это вместе. Отдельные примеры Я нашел адреса разных частей и некоторые уродливые обходные пути, но ничего, что просто позволило бы внешнему пользователю вызвать cast
и получить исключение, это отличное отключение. Некоторые вещи тоже старые, я использую Scala 2.10.5.
Зачем вам нужен второй способ произнесения (для итерацию)? Первого должно быть достаточно. – roterl
Я думаю, что я не вижу проблемы. 'def cast (m: Map [String, Any], key: String) = m (key) match {case x: Int => x}' правильно возвращает целое число и бросает с набором. Для определения типа набора может потребоваться classtags, но он работает с вашим примером – Archeg
, который изменяет заголовок для 'cast', и я не хочу, чтобы он кидал с помощью набора, я хочу, чтобы набор был корректным. Кроме того, вызов 'cast [Set [Char]]' автоматически не вызывает вторую перегрузку, даже более конкретную, чем первая. –