Elixir - 可以组合自定义地图类型吗?

skw*_*eth 1 elixir

在 Elixir 模块中定义类型时,是否可以合并两种不同的映射类型,其中一种是另一种的子集?例如:

defmodule Test do
  @typep map_a :: %{foo: String.t(), bar: String.t()}
  @typep map_b :: %{foo: String.t(), bar: String.t(), baz: String.t()}
end
Run Code Online (Sandbox Code Playgroud)

我想指出的是,该map_b类型是一个映射,本质上是一个实例map_a()加上附加baz键。我尝试过Map.merge(map_a(), %{baz: String.t})- 编译,但是当我通过 检查类型时t(Test),我只是得到了我写的内容,

@typep map_b :: Map.merge(map_a(), %{baz: String.t})
Run Code Online (Sandbox Code Playgroud)

这并没有让我深入了解这是否真的达到了我的目标。

使用Map.merge/2(或类似的东西)组合自定义地图类型是有效的方法吗?如果没有,这将如何实现?

Ale*_*kin 6

Map.merge/2不会\xe2\x80\x99t适用于规范,它\xe2\x80\x99实际上不是一个地图,它\xe2\x80\x99只是一个类似的语法。

\n

人们可以通过一些元编程来达到预期的结果。

\n
defmodule Test do\n  @map_a_type quote(do: [foo: String.t(), bar: String.t()])\n\n  @typep map_a :: %{unquote_splicing(@map_a_type)}\n  @typep map_b :: %{unquote_splicing(@map_a_type), baz: String.t()}\nend\n
Run Code Online (Sandbox Code Playgroud)\n