Scala: почему изменяемое значение внутри карты не может быть изменено, если карта создана из GroupBy - PullRequest
3 голосов
/ 16 марта 2019

Я хочу создать объект Map с ключом в виде целого числа и значением в виде изменяемого набора.Однако, когда я создаю свой объект Map из функции GroupBy, значение в моем изменяемом наборе больше не может быть изменено.Кто-нибудь может сказать, почему это произошло?

import scala.collection.mutable

val groupedMap: Map[Int, mutable.Set[Int]] = 
    List((1,1),(1,2),(2,3))
        .groupBy(_._1)
        .mapValues(_.map(_._2).to[mutable.Set])

val originalMap: Map[Int, mutable.Set[Int]] =
    Map(1 -> mutable.Set(1, 2), 2 -> mutable.Set(3))

println(groupedMap) // Map(1 -> Set(1, 2), 2 -> Set(3))
println(originalMap) // Map(1 -> Set(1, 2), 2 -> Set(3))

groupedMap(1) += 99
originalMap(1) += 99

println(groupedMap) // Map(1 -> Set(1, 2), 2 -> Set(3))  <- HERE IS THE PROBLEM, THE VALUE 99 CAN NOT BE ADDED TO MY MUTABLE SET!
println(originalMap) // Map(1 -> Set(99, 1, 2), 2 -> Set(3))

1 Ответ

11 голосов
/ 16 марта 2019

.mapValues является ленивым, что означает, что функция, которую вы даете ему, выполняется каждый раз, когда вы получаете доступ к значению, поэтому, когда вы делаете groupedMap(1) += 99, она запускает ваше преобразование, возвращает Set, к которому вы добавили 99, и отбрасывает его .

Затем, когда вы печатаете его, он снова запускает преобразование ... и печатает оригинальное содержимое.

Если приведенное выше неочевидно, попробуйте запустить этот фрагмент в качестве иллюстрации:

 val foo = Map("foo" -> "bar")
   .mapValues { _ => println("mapValues"); "baz" }

 println(foo("foo") + foo("foo"))

Это одна из многих проблем, с которыми вы сталкиваетесь при использовании изменяемых данных. Не делай этого. В 99% случаев использования в scala это не нужно. Таким образом, лучше всего делать вид, что его вообще не существует, пока вы не получите достаточно понимания языка, чтобы иметь возможность окончательно определить оставшийся 1%.

...