问题
Given the following code
defmodule Test do
def run do
p1 = {1, 2}
m1 = %{a: p1}
m2 = %{a: p1}
IO.puts :erts_debug.same(m1.a, m2.a)
m3 = %{b: p1}
IO.puts :erts_debug.same(m1.a, m3.b)
end
end
why does Test.run
prints this
iex(1)> Test.run
true <--- expected
false <--- not true ?!
:ok
Why are m1.a
and m3.b
not the same in-memory tuple?
回答1:
modern era update: seems like it was fixed in ≈v1.7.
This is true for Elixir only; in Erlang the tuple is shared:
1> Tuple = {1, 2},
1> Key1 = 1,
1> Key2 = 2,
1> Map1 = #{1 => Tuple, 2 => Tuple},
1> erts_debug:same(maps:get(Key1,Map1), maps:get(Key2,Map1)).
true
2> Key3 = 3,
2> Map2 = #{3 => Tuple},
2> erts_debug:same(maps:get(Key1,Map1), maps:get(Key3,Map2)).
true
For Elixir, this is probably because of internal transpiler to erlang duplicates maps or like. I’d say this could be a great bug report to Elixir core.
In your example :erts_debug.same(m1.a, m2.a)
prints true
only due to :erts_debug.same(m1, m2) #⇒ true
, e.g. maps themselves share the same memory.
来源:https://stackoverflow.com/questions/53868207/why-is-data-sharing-in-elixir-erlang-not-working-for-the-same-tuple-in-two-map