2012-04-24 5 views
6

Предположим, у меня есть карта m: Map[Any, Int]. Теперь я хотел бы взять только записи (String, Int) из m и создать новую карту m1: Map[String, Int] с этими записями.Предупреждение о непроверенных типах в Scala?

Я пытаюсь сделать следующее:

val m1: Map[String, Int] = m collect {case e:(String, Int) => e}

Кажется, работает, но я получаю предупреждение: не переменной типа аргумент Строка в типе шаблона (String, Int) снят, так как она удаляется стирание.

Как я могу избавиться от предупреждения?

ответ

9

вы, вероятно, хотите:

val m1: Map[String, Int] = m collect {case (k:String, v:Int) => k->v} 
+1

Или даже' е @ (_: String, _ : Int) => e', я думаю. –

+0

@ DanielC.Sobral, который дает несоответствие типов в REPL, но интересно это следует: «Примечание: Any>: String, но карта признаков инвариантна по типу A. Вы можете изучить тип подстановочного символа, такой как' _>: String' " – virtualeyes

+0

О, я вижу. 'e' будет только элементами' (String, Int) ', но его тип не изменится. –

3

(Только для справки Что вы хотите virtualeyes’s answer..)

val m1: Map[String, Int] = m flatMap { e => 
    e._1 match { 
    case e1: String => Some(e1 -> e._2) 
    case _ => None 
    } 
} 
2

Тщательное тестирование покажет, что ваше решение фактически соответствует всем на карте, а не только записи типа (String, Int). Предупреждение компилятора говорит вам, что типы вашего матча будут выброшены во время выполнения, так что ваш код на самом деле делает что-то вроде этого:

val m1: Map[String, Int] = m collect {case e:Tuple2[Any,Any] => e.asInstanceOf[Tuple2[String,Int]]}

И призыв asInstanceOf не взорвется, так как ему только бросает в Tuple2, а бит (String, Int) снова теряется из-за стирания. Вы получите неприятный сбой при попытке итерацию против результата, хотя ...

Попробуйте это в РЕПЛ

val m:Map[String,Int] = Map("2" -> 3, 3 -> 4, "6" -> 10) collect {case e:(String, Int) => e} 
    // Oops, thought we would get '2' 
    m size 
    // Nothing wrong with this code except m contains some 
    // hidden nasties which causes us to blow up 
    for ((s:String, i:Int) <- m) yield s.length + i 

`

Смежные вопросы