Niedawno natknąłem się na to post, które "wprowadza" metodędla kolekcji Scala. Użycie jest proste:Używanie kolekcji na mapach w Scali
scala> val ints = List(1, "2", 3) collect { case i: Int => i }
ints: List[Int] = List(1, 3)
Teraz mapy są zasadniczo listy par klucz-wartość, które są reprezentowane przez krotki w Scala. Więc może chcesz spróbować czegoś takiego:
scala> val pairs = Map(1 -> "I", "II" -> 2)
pairs: scala.collection.immutable.Map[Any,Any] = Map(1 -> I, II -> 2)
scala> val intsToStrings = pairs collect { case pair: (Int, String) => pair }
Kompilator narzeka oczywiście ze względu na modelu wymazywania typu JVM, więc pierwszą rzeczą, którą staramy się przy użyciu typów egzystencjalne:
scala> val intsToStrings = pairs collect { case pair: (_, _) => pair }
intsToString: scala.collection.immutable.Map[Any,Any] = Map(1 -> I, II -> 2)
Chociaż kod przeszedł przez kompilator, a wynik jest "poprawny" (chcieliśmy par = = mamy pary), nadal nie dostaliśmy tego, co faktycznie chcieliśmy. Druga próba wygląda następująco:
scala> val intsToStrings = pairs collect {
| case pair: (_, _) if pair._1.isInstanceOf[Int] && pair._2.isInstanceOf[String] => pair
| }
intsToStrings: scala.collection.immutable.Map[Any,Any] = Map(1 -> I)
Ok, jesteśmy prawie na miejscu:
scala> val realIntsToRealStrings = intsToStrings map {
| pair => (pair._1.asInstanceOf[Int], pair._2.asInstanceOf[String])
| }
realIntsToRealStrings: scala.collection.immutable.Map[Int,String] = Map(1 -> I)
Zrobiliśmy to, ale zamiast odlewania tylko z (Any,Any)
do (Int,String)
faktycznie skopiowane każdej pary, a tym samym stworzył Nowa para.
Nadchodzi część z pytaniami. Jak wspomniałem "Kompilator narzeka oczywiście ..." Sprawiłem, że brzmiało to tak, jak naprawdę wiem o czym mówię. Ja nie! Wiem tylko, że Java nie miała od początku generycznych rodzajów. W pewnym momencie generics wszedł do Javy, ale nie do JVM. Tak więc kompilator sprawdza wszystkie typy, ale zaraz po uruchomieniu kodu JVM nie dba o typ parametryczny. Widzi tylko, że jest to Map
lub List
ale nie, że jest to Map[String, Int]
lub List[Int]
.
Oto moje pytanie.
Po sprawdzeniu, przesłaniu i mapowaniu, udało nam się przesłać Map[Any,Any]
do Map[String,Int]
. Czy jest lepszy sposób na robienie tego? Znaczy typy są tam, JVM po prostu nie je zobaczyć (o ile jestem zaniepokojony) ...
super thx ! Wiedziałem, że Scala jest na tyle groźna, aby to się stało;) – agilesteel
O, radość! Nowa specjalna postać (@), prawie to odgadłem. – Ciantic