如何使用if结构来查找ets表是否为空

时间:2013-10-29 08:35:09

标签: erlang ets

我是Erlang的新手。我有一个学校项目使用ets:table。 但在我想从ets:table中获取一些数据之前,我想使用if结构检查表是否为空。

 if 
   ets:first(Cal) =/= '$end_of_table' ->
     Event = ets:first(Cal),
     {TimeAtStart, Ref} = Event,
     NowTime = now(),
     Ms = timer:now_diff(NowTime, TimeAtStart)div 1000
   end,

现在这给了我一个错误:非法的守卫表达。

我不知道我做错了什么,请帮忙。

友好的问候

大安

2 个答案:

答案 0 :(得分:6)

if期待一个后卫序列。所以它失败了。您可以在if之前进行测试,并使用结果,但是使用您的代码,当您获得'$ end_of_table'时,它也将失败,因为您没有true语句。

我建议您为代码使用case语句:

case ets:first(Cal)  of
     '$end_of_table' ->
           {error,no_entry};
     {TimeAtStart, _Ref} ->
           {ok,timer:now_diff(now(), TimeAtStart)div 1000}
end,

答案 1 :(得分:2)

非法守卫声明来自于在if语句守卫中调用ets:first(Cal)函数。所以if ets:first(Cal) =/= '$end_of_table' ->无法正确编译。 Guard语句只有一小组可以使用的函数read about them here

此外,如果Erlang与其他语言的语句略有不同。一个条款至少必须评估为true。 Documentation on if statements解释了这种行为,以及如果没有子句的计算结果为true,则抛出错误。

因此,将ets:first(Cal)移到if语句之外并在代码中添加catch all case,应该可以正常工作:

Res = ets:first(Cal),
if 
  Res =/= '$end_of_table' ->
    Event = ets:first(Cal),
    {TimeAtStart, Ref} = Event,
    NowTime = now(),
    Ms = timer:now_diff(NowTime, TimeAtStart)div 1000;
  true -> ok %% you need a default clause
end,

但是,如果是我在做我的学校项目,我会尝试使用ets:info函数来检查表的大小,并在case语句中进行。结帐Documentation on the ets:info functionthe case statement

仅供参考:我不认为我在Erlang编程的整个过程中都使用了if语句。