类型列表 typespec 永远不会破坏契约

Typed list typespec never breaks the contract

如果您定义类型规范并使用不同类型的参数,它将显示类似于以下内容的错误:

binary() ... breaks the contract ... boolean()

例如这个类型规范:

@spec check?(binary) :: boolean

但它似乎不适用于类型列表,或者至少,它永远不会显示警告,如果我有一个接收字符串列表的方法,我会定义这个类型规范:

@spec check?([String.t]) :: boolean

然后我可以为列表定义任何规范,当 运行 透析器时它永远不会抱怨,即:

@spec check?(list(boolean)) :: boolean
@spec check?(list(Conn)) :: boolean
@spec check?(list(number)) :: boolean
@spec check?(list(integer)) :: boolean

这是故意的吗?看起来如果我定义了一个任何类型的列表 [any()]

还有其他方法可以实现吗?

发生这种情况的原因是所有列表类型都包含空列表作为有效值。

例如,在以下情况下:

  • 您使用可能为空的布尔值列表调用该函数
  • 该函数接受一个可能为空的字符串列表

Dialyzer 将断定存在一个可能的解决方案,即如果列表为空。由于 Dialyzer 仅在确定某段代码总是会崩溃时才打印警告,因此在这种情况下它不会打印警告。

我不知道有什么好的解决办法。如果你想明确要求非空列表,你可以使用例如nonempty_list(boolean) 而不是 list(boolean).