Эрланг кейс

У меня есть следующий код Erlang, и он выдает предупреждение следующим образом, когда я пытаюсь скомпилировать его, но это имеет смысл. Для функции нужны два аргумента, но мне нужно, чтобы шаблон соответствовал "всему остальному", а не x, y или z.

-module(crop).
-export([fall_velocity/2]).

fall_velocity(P, D) when D >= 0 ->
case P of
x -> math:sqrt(2 * 9.8 * D);
y -> math:sqrt(2 * 1.6 * D);
z -> math:sqrt(2 * 3.71 * D);
(_)-> io:format("no match:~p~n")
end.

crop.erl:9: Warning: wrong number of arguments in format call. 

Я пробовал анонимную переменную после io:format, но все равно это не радует.

2 ответа

Решение

В формате вы используете ~ стр. Это значит - напечатать значение. Поэтому вы должны указать, какое значение печатать.

последняя строка дела должна быть

_ -> io:format("no match ~p~n",[P])

Кроме того, формат io: возвращает "хорошо". Так что, если P не x y или z, ваша функция вернет 'ok' вместо числового значения. Я бы предложил возвращать помеченное значение для разделения правильных и ошибочных возвратов. Вид

fall_velocity(P, D) when D >= 0 ->
case P of
x -> {ok,math:sqrt(2 * 9.8 * D)};
y -> {ok,math:sqrt(2 * 1.6 * D)};
z -> {ok,math:sqrt(2 * 3.71 * D)};
Otherwise-> io:format("no match:~p~n",[Otherwise]),
            {error, "coordinate is not x y or z"}
end.

Чтобы сделать комментарии к другому ответу явными, я бы написал эту функцию следующим образом:

-module(crop).
-export([fall_velocity/2]).

fall_velocity(P, D) when D >= 0 ->
    case P of
        x -> math:sqrt(2 * 9.8 * D);
        y -> math:sqrt(2 * 1.6 * D);
        z -> math:sqrt(2 * 3.71 * D)
    end.

То есть не обрабатывайте неверный аргумент в выражении вашего дела. Если кто-то проходит foo в качестве аргумента вы получите ошибку {case_clause, foo} вместе с трассировкой стека, которая указывает на эту функцию и ее вызывающего. Это также означает, что эта функция не может передавать неверные значения в остальную часть кода в результате вызова с неверными аргументами.

возврате {ok, Result} | {error, Error} как в другом ответе одинаково действителен. Вам нужно будет выбрать вариант, который лучше всего подходит для вашего случая.

Другие вопросы по тегам