样本代码:
defmodule Foo do
def fast_cars_cache do
fast_cars =
{
%{color: "Red", make: "Mclaren", mileage: 15641.469},
%{color: "Blue", make: "Ferrari", mileage: 120012.481},
%{color: "Red", make: "Ferrari", mileage: 29831.021},
%{color: "Black", make: "Ferrari", mileage: 24030.674},
%{color: "Cobalt", make: "Ferrari", mileage: 412.811},
%{color: "Blue", make: "Koenigsegg", mileage: 250.762},
%{color: "Cobalt", make: "Koenigsegg", mileage: 1297.76},
%{color: "Titanium", make: "Koenigsegg", mileage: 5360.336},
%{color: "Blue", make: "Maserati", mileage: 255.78}
}
if Enum.member?(:ets.all(), :fast_cars_cache) do
:ets.delete(:fast_cars_cache)
:ets.new(:fast_cars_cache, [:duplicate_bag, :public, :named_table])
:ets.insert(:fast_cars_cache, fast_cars)
else
:ets.new(:fast_cars_cache, [:duplicate_bag, :public, :named_table])
:ets.insert(:fast_cars_cache, fast_cars)
end
end
def update_record do
fast_cars_cache()
old_record = :ets.first(:fast_cars_cache)
new_record =
%{color: "Black", make: old_record.make, mileage: 1641.469}
:ets.delete(:fast_cars_cache, {old_record})
|> IO.inspect(label: "Old record deleted")
:ets.insert(:fast_cars_cache, {new_record})
:ets.tab2list(:fast_cars_cache)
end
end输出:
iex(1)> Foo.update_record
Old record deleted: true
[
{%{color: "Red", make: "Mclaren", mileage: 15641.469},
%{color: "Blue", make: "Ferrari", mileage: 120012.481},
%{color: "Red", make: "Ferrari", mileage: 29831.021},
%{color: "Black", make: "Ferrari", mileage: 24030.674},
%{color: "Cobalt", make: "Ferrari", mileage: 412.811},
%{color: "Blue", make: "Koenigsegg", mileage: 250.762},
%{color: "Cobalt", make: "Koenigsegg", mileage: 1297.76},
%{color: "Titanium", make: "Koenigsegg", mileage: 5360.336},
%{color: "Blue", make: "Maserati", mileage: 255.78}},
{%{color: "Black", make: "Mclaren", mileage: 1641.469}}
]意见/问题:
IO.inspect的说法,old_record已经被删除了,正如tab2list所揭示的那样,这个记录仍然存在。为什么会这样呢?old_record从未被删除,那么代码需要进行哪些调整才能完成这一任务?:ets.select_replace (如果适用的话)在一步内执行此更新,但我不能根据匹配规范的要求确定规定的正面或反面。如果有人能够根据上面的示例用一两个例子来消除歧义,那将是非常有帮助的。一如既往,非常感谢您的有益指导和建议:)
发布于 2020-06-02 04:43:50
你应该清楚地区分地图和元组。Map是一种键值结构.Tuple不是。
:ets 记录是元组,而不是映射。
您的初始结构是一组地图。一个元组,有很多地图。它作为单个元素插入到:ets中,这在输出中是明显可见的(请检查大括号)。
我猜您将在缓存中插入许多元素。
iex|1 ▶ :ets.new(:fast_cars_cache, [:duplicate_bag, :public, :named_table])
iex|2 ▶ fast_cars = [
...|2 ▶ {"Red", "Mclaren", 15641.469},
...|2 ▶ {"Blue", "Ferrari", 120012.481},
...|2 ▶ {"Red", "Ferrari", 29831.021}
...|2 ▶ ]
iex|3 ▶ :ets.insert(:fast_cars_cache, fast_cars)正如文档中所述,:ets.first/1返回第一个键。:ets.detele/2按键删除记录,您的代码将从:ets.first/1返回的任何内容封装到一个单元素元组中,使得:ets.delete/2无论如何都成为无操作(是的,:ets.delete/2总是返回true)。
iex|4 ▶ :ets.first(:fast_cars_cache)
#⇒ "Red"
iex|5 ▶ :ets.delete(:fast_cars_cache, {"Red"}) # NOOP
#⇒ true
iex|6 ▶ :ets.delete(:fast_cars_cache, "Red") # DELETED
#⇒ true然后,如果您想插入一个新记录,创建一个元组并插入它,不要创建一个封装在单个元素元组中的映射。要按键获取旧记录,通常使用:ets.lookup/2或更复杂的:ets.select。
iex|7 ▶ [{_, make, _}|_] = :ets.lookup(:fast_cars_cache, "Red")
iex|8 ▶ new_record = {"Black", make, 1641.469}
iex|9 ▶ :ets.insert(:fast_cars_cache, new_record)我已经链接了足够多的文档,可以使用:ets.select_replace/2作为作业离开。
https://stackoverflow.com/questions/62143679
复制相似问题