Erlang从父类型中排除类型

b91juud3  于 2022-12-08  发布在  Erlang
关注(0)|答案(3)|浏览(130)

在Erlang中,是否可以通过从父类型中排除子类型来定义类型?举个例子,我如何定义一个类型“anything but pid()“:

-type anything_but_pid() :: ...?

在阅读有关Supervisor数据类型的文档时,我遇到了child_id()的类型规范,它将类型定义为term(),然后在下面的注解中显示为Not a pid()
child_id() = term()
不是一个pid()
如果我不想显式地列出所有可能的类型,这是我能做的最好的吗?

rnmwe5a2

rnmwe5a21#

不支持,从OTP 23(甚至24)开始,不支持此功能。
此外,期望Dialyzer在这样的情况下提供帮助是不明智的,因为Dialyzer经常过于近似,原因有几个,尽管我不认为它会立即将这样的类型转换为term(),但它很可能在第一次给出机会时就这样做(例如,无论你在哪里调用这样的函数)。

ecfsfe2w

ecfsfe2w2#

作为一种可能的解决方法,您可以为函数定义一个规范,如下所示:

-spec foo(pid()) -> ...;
             (any()) -> ...
    foo(data) when is_pid(data) -> error;
    foo(data) -> ....
2w3rbyxf

2w3rbyxf3#

特别是对于anything_but_pid(),您可以“简单地”枚举所有其他选项:

-type anything_but_pid() :: port()
                          | reference()
                          | atom()
                          | bitstring()
                          | number()
                          | fun()
                          | maybe_improper_list()
                          | map()
                          | tuple()

当然,这并不能一概而论......

相关问题