Elixir typespec的含义是什么,括号中的类型由管道运算符分隔?

时间:2018-01-10 21:46:43

标签: elixir typespec

我将Elixir库移植到使用类型规格的Elm,但我在查找某些语法的文档时遇到了问题。

以下表达的表达式是什么?

@type identifier :: (String.t | MyCustomTypeA.t | MyCustomTypeB.t)

最初我将其建模为元组,但现在我正在查看它的用法,看起来好像它可能是一个被歧视的联盟。这个假设的问题是我在这里没有看到任何支持这些事情的文档(http://elixir-lang.github.io/getting-started/typespecs-and-behaviours.html)。

1 个答案:

答案 0 :(得分:3)

你是对的,因为它是一个被歧视的联盟。 Elixir和Erlang文档都没有直接调用它,但可以从更深入的文档中推断出来(https://hexdocs.pm/elixir/typespecs.html

对此唯一真正的要求就是

  

所有其他类型都是由预定义类型的联合构建的。

在您的示例中,不需要括号。你也可以把它写成

@type identifier :: String.t | MyCustomTypeA.t | MyCustomTypeB.t

这意味着identifier可以是String.tMyCustomTypeA.tMyCustomTypeB.t

Elixir从Erlang继承了这一点,并在Learn you some Erlang for great good

中得到了很好的解释

(请记住,虽然Elixir构建于Erlang上,但语法略有不同)

  

Erlang具有联合类型,它允许您描述其中包含两个原子的类型,以及内置类型,这些类型是预定义类型,不一定可以手动构建,并且它们通常是是有用的。

     

[... SNIP ...]

     

表示类型联合的表示法是管道(|)。基本上,这让我们说给定类型TypeName表示为Type1 |的并集Type2 | ...... | typen的。因此,number()类型(包括整数和浮点值)可以表示为integer()|浮动()。布尔值可以定义为' true' | '假&#39 ;.还可以定义仅使用一种其他类型的类型。虽然它看起来像一个联合类型,但它实际上是一个别名。