/ / Scala Niezmienne mapy Kowariancja - scala, kowariancja

Scala Mapy niezmienne Kowariancja - scala, kowariancja

Staram się pojąć kowariancję i kontrawariancję w Scali. Mam taki zestaw klas Wiadomość 1 i Wiadomość 2 są podtypami komunikatu

sealed trait Parser[T <: Message]{
//... blah blah
}

class Parser1 extends Parser[Message1]{
}

class Parser2 extends Parser[Message2]{
}

Teraz mam inny moduł (fabryka), który przechowuje mapowania na niezmiennej mapie

var myMap = Map[String,Parser[Message]()
myMap += Map("Message1" -> new Parser1)
myMap += Map("Message2"-> new Parser2)

Teraz to się nie kompiluje. czego mi brakuje?

To błąd kompilacji, który otrzymuję

[error]  found   : scala.collection.immutable.Map[java.lang.String,s.p.h.m.Parser1]
[error]  required: (String, s.p.h.m.Parser[c.s.m.Message])
[error]   myMap += Map("Message1" -> new Parser1)

Odpowiedzi:

2 dla odpowiedzi № 1

Widziałeś już, że potrzebujesz ++= aby dodać wpisy innej mapy do mapy, podczas gdy + przyjmuje pojedynczy wpis (krotkę klucza i wartości). Jeśli chcesz zachować var, musisz się tego upewnić Parser jest kowariantem w T po to aby Parser[Message1] jest uważany za podtyp Parser[Message] (ponieważ wynik + będzie najbliższym nadtypem istniejących wpisów i nowego wpisu, który w takim przypadku pozostanie Map[String,Parser[Message]] i dlatego można go ponownie zapisać w myMap):

trait Message; class Message1 extends Message; class Message2 extends Message

sealed trait Parser[+T <: Message]  // !
class Parser1 extends Parser[Message1]
class Parser2 extends Parser[Message2]

var myMap = Map.empty[String,Parser[Message]]
myMap += "Message1" -> new Parser1
myMap += "Message2"-> new Parser2
myMap ++= Map( "Message1b"-> new Parser1, "Message2b"-> new Parser2 )

2 dla odpowiedzi nr 2

Jaki błąd otrzymujesz? Nie wygląda to tak, jakbyś miał tutaj jakieś błędy typu z powodu twojego Parser hierarchia klas.

Wygląda jednak na to, że próbujesz zmutować niezmienną mapę i tak dalej byłoby spowodować błąd. Powinieneś także dodać para map do mapy zamiast nowa mapa. Spróbuj tego:

val myMap = Map[String,Parser]()
val myMap1 = myMap + ("Message1" -> new Parser1)
val myMap2 = myMap1 + ("Message2" -> new Parser2)

Jeśli naprawdę chcesz skorzystać += zamiast tworzyć nowy val dla każdej aktualizacji możesz użyć scala.collection.mutable.Map zamiast domyślnego (niezmiennego) typu mapy.