Elixir - 类型规格


Elixir 是一种动态类型语言,因此 Elixir 中的所有类型都是由运行时推断的。尽管如此,Elixir 附带了类型规范,这是一种用于声明自定义数据类型和声明类型化函数签名(规范)的符号。

功能规格(spec)

默认情况下,Elixir 提供了一些基本类型,例如整数或 pid,也提供了复杂类型:例如,round函数将浮点数四舍五入到最接近的整数,将数字作为参数(整数或浮点数)并返回一个整数。在相关文档中,圆形签名写为 -

round(number) :: integer

上面的描述意味着左边的函数将括号中指定的内容作为参数,并返回 :: 右边的内容,即 Integer。函数规范是用@spec指令编写的,位于函数定义之前。轮函数可以写为 -

@spec round(number) :: integer
def round(number), do: # Function implementation
...

类型规范也支持复杂类型,例如,如果你想返回整数列表,那么你可以使用[Integer]

自定义类型

虽然 Elixir 提供了许多有用的内置类型,但在适当的时候定义自定义类型也很方便。这可以在通过 @type 指令定义模块时完成。让我们考虑一个例子来理解同样的内容 -

defmodule FunnyCalculator do
   @type number_with_joke :: {number, String.t}

   @spec add(number, number) :: number_with_joke
   def add(x, y), do: {x + y, "You need a calculator to do that?"}

   @spec multiply(number, number) :: number_with_joke
   def multiply(x, y), do: {x * y, "It is like addition on steroids."}
end

{result, comment} = FunnyCalculator.add(10, 20)
IO.puts(result)
IO.puts(comment)

当上面的程序运行时,它会产生以下结果 -

30
You need a calculator to do that?

注意- 通过 @type 定义的自定义类型将被导出并在定义它们的模块外部可用。如果您想将自定义类型保持私有,您可以使用@typep指令而不是@type