Sto cercando di implementare un nuovo tipo, Chunk, che è simile a una mappa. Fondamentalmente, un "Chunk" è una mappatura da String -> Chunk, o una stringa stessa.scala mappa personalizzata
esempio che dovrebbe essere in grado di lavorare in questo modo:
val m = new Chunk("some sort of value") // value chunk
assert(m.getValue == "some sort of value")
val n = new Chunk("key" -> new Chunk("value"), // nested chunks
"key2" -> new Chunk("value2"))
assert(n("key").getValue == "value")
assert(n("key2").getValue == "value2")
ho questo per lo più a lavorare, se non che sono un po 'confuso da quanto l'operatore + funziona per le mappe immutabili.
Ecco quello che ho adesso:
class Chunk(_map: Map[String, Chunk], _value: Option[String]) extends Map[String, Chunk] {
def this(items: (String, Chunk)*) = this(items.toMap, None)
def this(k: String) = this(new HashMap[String, Chunk], Option(k))
def this(m: Map[String, Chunk]) = this(m, None)
def +[B1 >: Chunk](kv: (String, B1)) = throw new Exception(":(do not know how to make this work")
def -(k: String) = new Chunk(_map - k, _value)
def get(k: String) = _map.get(k)
def iterator = _map.iterator
def getValue = _value.get
def hasValue = _value.isDefined
override def toString() = {
if (hasValue) getValue
else "Chunk(" + (for ((k, v) <- this) yield k + " -> " + v.toString).mkString(", ") + ")"
}
def serialize: String = {
if (hasValue) getValue
else "{" + (for ((k, v) <- this) yield k + "=" + v.serialize).mkString("|") + "}"
}
}
object main extends App {
val m = new Chunk("message_info" -> new Chunk("message_type" -> new Chunk("boom")))
val n = m + ("c" -> new Chunk("boom2"))
}
Inoltre, commenta sia, in generale, questa implementazione è opportuno sarebbe apprezzato.
Grazie!
Modifica: la soluzione dei tipi di dati algebrici è eccellente, ma rimane un problema.
def +[B1 >: Chunk](kv: (String, B1)) = Chunk(m + kv) // compiler hates this
def -(k: String) = Chunk(m - k) // compiler is pretty satisfied with this
l'operatore - qui sembra funzionare, ma l'operatore + mi ha davvero vuole restituire qualcosa di tipo B1 (credo)? Viene a mancare con il seguente problema:
overloaded method value apply with alternatives: (map: Map[String,Chunk])MapChunk <and> (elems: (String, Chunk)*)MapChunk cannot be applied to (scala.collection.immutable.Map[String,B1])
Edit2: Xiefei risposto a questa domanda - che si estende mappa richiede che io gestire + con un supertipo (B1) di Chunk, quindi per fare questo devo avere alcuni implementazione per questo, quindi questo sarà sufficiente:
def +[B1 >: Chunk](kv: (String, B1)) = m + kv
Tuttavia, non ho mai veramente intenzione di utilizzare quella, invece, sarò anche includere mia implementazione che restituisce un pezzo come segue:
def +(kv: (String, Chunk)):Chunk = Chunk(m + kv)
L'implementazione per '+', nel caso di mappe immutabili, deve restituire una nuova mappa con la chiave/valore aggiunto, giusto? Hai già "avvolto" una mappa ('_map'), quindi per un'implementazione del tuo' + ', solo la delega a' _map' funzionerà: 'def + [B1>: Chunk] (kv: (String, B1)) = _map + kv'. Il vero problema è che questo non ha assolutamente senso per "semplici" Chunk's (quelli che sono solo una stringa). In altre parole, avendo l'insieme di costruttori che descrivi sopra, ** e ** che implementano '+' interrompe la definizione di un 'Chunk' ... perché consente a un pezzo di stringa di // anche // diventare una mappa- pezzo. – Faiz