Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/github/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Types 如何在erlang中使用-spec功能_Types_Casting_Erlang - Fatal编程技术网

Types 如何在erlang中使用-spec功能

Types 如何在erlang中使用-spec功能,types,casting,erlang,Types,Casting,Erlang,我正在编写一个小型的erlang服务,我想对我的类型进行约束 我已经找到了功能,在我看来,这是一种将函数签名“锁定”到特定类型的方法 我的示例是这样一个函数: fib(N) when N < 3 -> 1; fib(N) -> fib(N-1) + fib(N-2). 应该确保该方法至少返回正确的类型,但情况似乎并非如此 如果我将函数更改为: fib(N) when N < 3 -> ok; fib(N) -> not_ok.

我正在编写一个小型的erlang服务,我想对我的类型进行约束

我已经找到了功能,在我看来,这是一种将函数签名“锁定”到特定类型的方法

我的示例是这样一个函数:

fib(N) when N < 3 ->
    1;
fib(N) ->
    fib(N-1) + fib(N-2).
应该确保该方法至少返回正确的类型,但情况似乎并非如此

如果我将函数更改为:

fib(N) when N < 3 ->
    ok;
fib(N) ->
    not_ok.
当N<3-> 好啊 fib(N)-> 不好。 代码仍然可以编译,很好,甚至可以运行


我误解了什么?

编译器跳过这些注释。但您可以使用透析器进行静态代码分析。此工具将警告您违反规范

如中所述,
-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(伪)
fib(0.5)
甚至
fib(-1)
的操作。如果您尝试,它将在运行时失败,并出现
错误匹配


注意:在中只能使用运行时允许的内置函数。大多数都在模块中。

这是否意味着为了确保代码“稳定”,您必须在编译器的顶部运行透析器工具?这就是你解决整个打字问题的方法吗?@MartinKristiansen是的,如果你想要稳定的生产代码,你应该运行透析器。也许不是每次构建,而是周期性的。例如,如果您使用daily build system,您可以将其与daily build system集成。我明白了,但我真正想要的是某种静态类型检查,比如在ML中。这意味着我想指定一个类型a:=C | D。然后定义方法,使其具有类型,例如(|->a)。你知道有哪些具有良好并发机制的语言能够完成这类工作吗?@MartinKristiansen:dialyzer是标准的erlang工具。它随erlang一起提供,应该在任何erlang项目中使用。是的,静态分析不是编译器的一部分,但无论如何,您可以随时进行。想象一下,若C预处理器是独立于编译器的工具。这会有点不舒服,但好吧。顺便说一句,您的类型规范应该看起来像
-spec fib\u cps(pos\u integer())->pos\u integer()。
(注意空括号),否则透析器会认为您指的是原子
pos\u integer
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).