Как использовать функциональность -spec в erlang - PullRequest
6 голосов
/ 14 декабря 2011

Я пишу небольшой сервис Erlang, и я хотел бы наложить ограничения на мои типы.

Я обнаружил функциональность -spec , и мне кажется, что это способ «привязать» сигнатуры функций к определенным типам.

Мой пример будет такой функцией:

fib(N) when N < 3 ->
    1;
fib(N) ->
    fib(N-1) + fib(N-2).

добавление строки

-spec fib_cps(pos_integer()) -> pos_integer().

должен убедиться, что метод atleast возвращает правильный тип, но это не так ..

для Если я изменю функцию на:

fib(N) when N < 3 ->
    ok;
fib(N) ->
    not_ok.

код все еще компилируется, нормально работает и даже запускается.

Что я недопонимаю?

Ответы [ 2 ]

11 голосов
/ 14 декабря 2011

Компилятор пропускает эти комментарии.Но вы можете использовать диализатор для статического анализа кода.Этот инструмент предупредит вас о нарушениях спецификаций.

1 голос
/ 15 декабря 2011

Как оборотень говорит в другой ответ , -spec используется только для анализа, а не как часть подписи.Если вы хотите проверить типы ввода, вы можете включить проверки для типа в охране.Итак, в вашем примере вы можете сделать:

fib(N) when is_integer(N), N > 0, N < 3 ->
    1;
fib(N) when is_integer(N), N >= 3 ->
    fib(N-1) + fib(N-2).

Или, более идиоматически, поскольку есть только два законных базовых случая:

fib(1) -> 1;
fib(2) -> 1;
fib(N) when is_integer(N), N >= 3 ->
    fib(N-1) + fib(N-2).

Это помешает вам сделать что-то вродеfib(bogus) или fib(0.5) или даже fib(-1).Если вы попытаетесь это сделать, произойдет сбой с badmatch во время выполнения.

Примечание: единственными функциями, которые вы можете использовать в guard , являются встроенные функции, разрешенные средой выполнения.Большинство из них находятся в модуле erlang.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...