Generics elixir:定义映射/哈希表的类型规范

Generics elixir:定义映射/哈希表的类型规范,generics,types,static-analysis,elixir,Generics,Types,Static Analysis,Elixir,在带有泛型的静态类型语言中,如C#,我可以在方法签名中指定映射的每个键是一个原子,每个值是一个{string,int}元组列表。如何为Elixir中的函数参数定义类型规范 PS:如果您正在阅读此文件,并且评级>1500,请您创建一个类型规范标签 您可以这样定义它: @type bar :: %{atom => [{binary, integer}]} @spec foo(bar) :: bar def foo(bar), do: bar 上面定义了一个新类型,它是原子键到二进制/整数元

在带有泛型的静态类型语言中,如C#,我可以在方法签名中指定映射的每个键是一个原子,每个值是一个{string,int}元组列表。如何为Elixir中的函数参数定义类型规范


PS:如果您正在阅读此文件,并且评级>1500,请您创建一个类型规范标签

您可以这样定义它:

@type bar :: %{atom => [{binary, integer}]}

@spec foo(bar) :: bar
def foo(bar), do: bar

上面定义了一个新类型,它是原子键到二进制/整数元组列表的映射,然后在
foo

的类型规范中使用该类型。对于内联规范,它如下所示:

defmodule LousyCalculator do
  @spec add(number, number) :: {number, String.t}
  def add(x, y), do: {x + y, "You need a calculator to do that?!"}

  @spec multiply(number, number) :: {number, String.t}
  def multiply(x, y), do: {x * y, "Jeez, come on!"}
end
如果需要结构,则类型为:

@spec struct_returner_and_getter(%Struct_name1{}) :: %Struct_name2{}

来源:

我不熟悉elixir,但它声称是一种“动态语言”,这通常意味着它没有正式的类型系统。所以使用注释?它有类型规范,可供静态分析工具透析器使用-只是为了确保,我必须事先将其指定为类型,我不能直接内联它?如果是这样,我是否应该将所有自定义类型保留在一个单独的模块中,然后直接导入它们,以避免在多个模块中复制粘贴类型定义?您当然可以将其内联,但如果有多个复杂类型都内联,我会发现很难阅读。它也更明确地说明了类型是什么,而不仅仅是它的结构。您可以在其他模块中定义类型,并通过
模块使用它们。键入\u name
。太好了,谢谢!从这个意义上说,Elixir的静态分析比Go的更细粒度,因为Go不允许您定义将自定义类型作为参数的函数。(如果您没有使用Go,则不考虑)我应该澄清
def foo(bar)
中的
bar
实际上并不是指类型,而是反映与您期望
foo
接收的值类型相匹配的变量的命名。您可以使用
foo(5)
调用该函数,它可以很好地编译。只有当您运行透析器时,才会出现错误,让您知道您将错误的类型传递到
foo
。这就是说,它在静态分析期间提供了更大程度的信息,这可能非常有用。Dialyzer会检查函数中的代码元素,包括对具有类型规范的其他函数的调用。它不仅限于函数签名。