Elixir - 类型规范

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

功能规格(specs)

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

round(number) :: integer

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

@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