O (1) преобразование из изменяемого. Карта в неизменяемый. Карта? - PullRequest
14 голосов
/ 17 марта 2010

Есть ли способ преобразовать (обернуть) изменяемую Карту в неизменяемую за O (1) время (то есть, не копируя значения, но аналогично тому, что делается в JavaConversions)

Ответы [ 5 ]

6 голосов
/ 17 марта 2010

Как указывает Томас, представление только для чтения - O (1). Но только чтение не означает неизменность.

Разница хорошо описана в статье " Fighting Bit Rot * ":

Все классы коллекции хранятся в пакет scala.collection. Этот пакет имеет три подпакета: изменяемый, неизменный и общий. Наиболее коллекции существуют в трех формах, в зависимости от их изменчивости.

Коллекция в упаковке scala.collection.immutable is гарантированно будет неизменным для каждый. Это означает, что можно положиться на тот факт, что доступ к тому же стоимость коллекции со временем всегда будет собрать коллекцию с тем же элементы. Коллекция в упаковке scala.collection.mutable известен есть некоторые операции, которые меняют коллекция на месте.

Коллекция в упаковке scala.collection может быть изменяемой или неизменный. Например, collection.Seq [T] является суперклассом оба collection.immutable.Seq [T] и collection.mutable.Seq [Т]. В общем-то, корневые коллекции в пакете scala. Коллекция определяет тот же интерфейс как неизменные коллекции, и изменяемые коллекции в упаковке scala.collection.mutable обычно добавляют некоторая деструктивная модификация операции к этому неизменному интерфейс. разница между корневые коллекции и неизменные Коллекции в том, что пользователь неизменная коллекция имеет гарантию что никто не может изменить коллекцию, тогда как пользователи корневых коллекций имеют предполагать изменения, сделанные другими, даже если они не могут сделать сами модификации.

Возможно, это просто, как повышение.

scala> val mm = collection.mutable.Map(1 -> 2)
mm: scala.collection.mutable.Map[Int,Int] = Map(1 -> 2)

scala> val readOnly = mm : collection.Map[Int, Int]
readOnly: scala.collection.Map[Int,Int] = Map(1 -> 2)
3 голосов
/ 17 марта 2010

В принципе, можно добавить метод «заморозки» к изменяемой структуре данных, которая предотвращает дальнейшую мутацию. Это единственный, даже слегка безопасный способ сделать обертку. (Немного, потому что после этого вам придется генерировать исключения, когда вы пытаетесь изменить его.) Однако изменяемые коллекции Scala не имеют такой возможности. Можно добавить это, например, к mutable.HashMap, переопределяя все методы мутирования (update, +=, ++= и т. д.), но это было бы неплохо.

3 голосов
/ 17 марта 2010

То, о чем вы просите, небезопасно. Вы можете передать mutable.Map как collection.Map, который является неизменным, но «клиенты», использующие эту форму, не могут быть уверены, что их представление не изменится из-под них.

3 голосов
/ 17 марта 2010

Существует проекция только для чтения для изменяемых карт.

scala> collection.mutable.Map(1->2).readOnly
res0: scala.collection.Map[Int,Int] = ro-Map(1 -> 2)

Как указывало oxbow_lakes базовая Карта по-прежнему изменчива и может измениться после публикации проекции только для чтения для клиентов. Иллюзия неизменности должна быть рассмотрена в коде, управляющем картой.

2 голосов
/ 18 марта 2010

Работа Филиппа Халлера над Возможности для уникальности и заимствования связана с этим. В области принудительного «владения» через систему типов существует много другой работы, но Филипп фактически предоставляет полезный плагин для компилятора Scala.

...