Elixir中的小写或大写@spec

Elixir中的小写或大写@spec,elixir,Elixir,在@spec中,有时我会看到这样的定义 @spec a_函数(整数、映射、列表):{:好的,映射} 有时@spec a_函数(整数、映射、列表):{:好的,映射} 哪一个是正确的方法? 我找不到任何具体的答案 谢谢即使你把垃圾放在那里,一切都会被编译好的@spec仅由透析器使用,编译器在定义术语(例如原子)时安全地忽略它们,并且@spec的算术符合定义的函数之一。这将起作用: @spec call(Foo, Bar, Baz, Boo) :: BLAH def call(p1, p2, p3,

@spec
中,有时我会看到这样的定义
@spec a_函数(整数、映射、列表):{:好的,映射}

有时
@spec a_函数(整数、映射、列表):{:好的,映射}

哪一个是正确的方法? 我找不到任何具体的答案


谢谢

即使你把垃圾放在那里,一切都会被编译好的
@spec
仅由透析器使用,编译器在定义术语(例如原子)时安全地忽略它们,并且
@spec
的算术符合定义的函数之一。这将起作用:

@spec call(Foo, Bar, Baz, Boo) :: BLAH
def call(p1, p2, p3, p4), do: 42
只有拨号器会在这里发出警告,说
42
不匹配
BLAH

这就是说,
@spec
中的所有术语都必须在编译时解析。虽然它们是有效的原子(
Integer
Map
List
显然是有效的原子),但规范有点道理,但不会产生任何编译错误


这种表示法虽然更好,但也不正确。它之所以有效,是因为各自的类型是用函数
integer()
map()
list()
声明的,尽管不鼓励使用,但仍然可以使用不带括号的函数调用。总而言之,编写规范的正确方法是:

@spec a_function(integer(), map(), list()) :: {:ok, map()}

可以使用
@type
模块属性声明自己的类型,由未记录的模块处理:

然后将其用作:

@spec my(MyStruct.t()) :: any
def my(str), do: str.foo

即使你把垃圾放在那里,一切都会被编译好的
@spec
仅由透析器使用,编译器在定义术语(例如原子)时安全地忽略它们,并且
@spec
的算术符合定义的函数之一。这将起作用:

@spec call(Foo, Bar, Baz, Boo) :: BLAH
def call(p1, p2, p3, p4), do: 42
只有拨号器会在这里发出警告,说
42
不匹配
BLAH

这就是说,
@spec
中的所有术语都必须在编译时解析。虽然它们是有效的原子(
Integer
Map
List
显然是有效的原子),但规范有点道理,但不会产生任何编译错误


这种表示法虽然更好,但也不正确。它之所以有效,是因为各自的类型是用函数
integer()
map()
list()
声明的,尽管不鼓励使用,但仍然可以使用不带括号的函数调用。总而言之,编写规范的正确方法是:

@spec a_function(integer(), map(), list()) :: {:ok, map()}

可以使用
@type
模块属性声明自己的类型,由未记录的模块处理:

然后将其用作:

@spec my(MyStruct.t()) :: any
def my(str), do: str.foo

我甚至不确定第一个选项是否正确,但第二个选项肯定是正确的,这是常见的方法。如果我使用第一个方法,我不会出现任何错误,并且一切都可以正常运行。这就是为什么我想问。我甚至不确定第一个选项是否正确,但第二个选项肯定是正确的,这是常见的方法。如果我使用第一个方法,我不会出现任何错误,并且一切都可以正常编译。这就是为什么我想问。