Eliminare del tutto la covarianza sarebbe, naturalmente, non corretto e non consentito. Dato m: Map[A, String]
e v : Any
, è possibile eseguire val mm : Map[A, Any] = m + v
. Questo è ciò che dice la definizione Map
e tutti gli implementatori devono seguire. La tua classe potrebbe essere invariata, ma deve implementare l'intera interfaccia covariante di Map.
Ora la ridefinizione di +
per generare un errore è una storia diversa (non molto valida ancora). Il problema con il tuo nuovo metodo +
è che dopo la cancellazione generica, ha la stessa firma dell'altro metodo +
. C'è un trucco: aggiungi un parametro implicito, in modo da avere due parametri nella firma, il che lo rende diverso dal primo.
def +(kv : (A,B))(implicit useless: A <:< A) : MyMap[A,B]
(non importa cosa implicita parametro che stai cercando, fino a quando uno si trova implicit useless: Ordering[String]
. Funziona altrettanto bene)
Facendo questo, si ha il solito problema con sovraccarico . Se si aggiunge una B senza che il compilatore lo sappia, verrà chiamato il metodo fallito. Potrebbe essere meglio eseguire un controllo del tipo in modo che le istanze B siano accettate in qualsiasi modo. Ciò richiederebbe un Manifesto [B] nella tua mappa.
fonte
2011-08-17 23:15:28
Forse potresti usare una mappa membro invece di derivare? – Owen
Inoltre, perché ha bisogno di essere invariato? Ho pensato (anche se non conosco molto Scala) l'unica volta che hai bisogno di invarianza è se può essere sia una fonte che un sink, ma le mappe sono immutabili quindi non può essere un sink. – Owen
Voglio implementare una mappa bidirezionale. Non è un grosso problema se implemento Map e deleghiamo solo le due mappe interne che definiscono la mappatura in avanti e indietro, ma in questo caso ho bisogno di invarianza. –