Jas*_*ith 5 erlang foreach ets
简短版本:ets:foldl当一个人正在迭代它们时,是否可以安全地删除每个ETS记录?
假设一个ETS表正在累积信息,现在是时候处理它了.从表中读取记录,以某种方式使用,然后删除.(另外,假设表是private,所以没有并发问题.)
在另一种语言中,使用类似的数据结构,您可以使用for ... each循环,处理每个记录,然后从hash/dict/map /中删除它.但是,该ets模块没有foreach例如lists.
但这可能有效:
1> ets:new(ex, [named_table]).
ex
2> ets:insert(ex, {alice, "high"}).
true
3> ets:insert(ex, {bob, "medium"}).
true
4> ets:insert(ex, {charlie, "low"}).
true
5> ets:foldl(fun({Name, Adjective}, DontCare) ->
io:format("~p has a ~p opinion of you~n", [Name, Adjective]),
ets:delete(ex, Name),
DontCare
end, notused, ex).
bob has a "medium" opinion of you
alice has a "high" opinion of you
charlie has a "low" opinion of you
notused
6> ets:info(ex).
[...
{size,0},
...]
7> ets:lookup(ex, bob).
[]
Run Code Online (Sandbox Code Playgroud)
这是首选方法吗?它至少是正确的,没有错误吗?
我对在处理数据结构时修改数据结构有一个普遍的关注,但是ets:foldl文档暗示ETS非常适合你修改里面的记录foldl.由于我基本上擦桌子干净,我想确定.
我正在使用带有set表的Erlang R14B 但是我想知道是否有任何Erlang版本或任何类型的表格的警告.谢谢!
你的方法很安全.它安全的原因是ets:foldl/3内部使用ets:first/1, ets:next/2和ets:safe_fixtable/2.这些都有你想要的保证,即你可以杀死元素并仍然获得完整的遍历.请参阅" CONCURRENCY"部分erl -man ets.
为了从表中删除所有元素,有一个更简单的单行:
ets:match_delete(ex, '_').
Run Code Online (Sandbox Code Playgroud)
虽然它不起作用你应该为每一行进行IO格式化,在这种情况下你的方法foldl可能更容易.