Erlang 无效的保护表达式

Erlang invalid guard expression

我正在尝试编写一个计算最大二进制倍数的程序。 (一个数的二进制倍数,例如 N,是原始数的倍数,仅由数字 01 组成。)

然而,表达式lists:max(hd(io_lib:format("~b", [N]))) < 50 抛出非法守卫表达式错误。我知道这是由于调用了一个不在保护序列 the allowed functions 中的函数,但我真的不知道如何避免这个错误。

有人可以解释一下如何避免这个错误吗?

% X: Multiple to be checked
% N: The accumulator
countup(X, N) -> % io:write([X, N]),
    if
        lists:max(hd(io_lib:format("~b", [N]))) < 50 ->
            N;
        true ->
            countup(X, N + X)
    end.

使用 case 而不是 if:

countup(X, N) -> % io:write([X, N]),
    case lists:max(hd(io_lib:format("~b", [N]))) < 50 of
        true ->
            N;
        false ->
            countup(X, N + X)
    end.

或者:

countup(X, N) -> % io:write([X, N]),
    case lists:max(hd(io_lib:format("~b", [N]))) of
        Max when Max < 50 ->
            N;
        _ ->
            countup(X, N + X)
    end.

一般来说,if在Erlang中很少使用。它最常见的用途之一是检查值属于哪个范围:

if X < 10 ->
        small;
   X >= 10, X < 20 ->
        medium;
   X >= 20 ->
        large
end

但在几乎所有其他情况下,case 会更合适。


您可以使用 integer_to_list(N) 而不是 hd(io_lib:format("~b", [N]))io_lib:format 保证 return 和 "iolist"(列表和字符串的嵌套列表),但不保证结果的具体形式,因此您的代码可能会在未来的 Erlang 版本中中断如果 io_lib:format 的实施发生变化。