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**。

广告