3

我是 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,

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

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

带着友好的问候

大安

4

2 回答 2

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,
于 2013-10-29T09:14:45.287 回答
2

非法守卫语句来自于在 if 语句守卫中调用 ets:first(Cal) 函数。所以if ets:first(Cal) =/= '$end_of_table' ->不会正确编译。Guard 语句只有一小部分可以使用的函数,在这里阅读它们

此外,Erlang 与其他语言中的 if 语句也略有不同。至少一个子句必须评估为真。if 语句的文档解释了这种行为,以及如果没有子句评估为 true,则如何引发错误。

因此,移动ets:first(Cal)if 语句的外部并在代码中添加一个 catch all tr​​ue 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 语句中进行。查看有关 ets:info 函数的文档和案例语句

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

于 2013-10-29T15:24:54.113 回答