为什么我不能正确地将地图作为参数在elixir中?

时间:2016-05-10 04:10:44

标签: elixir

我在elixir中玩use功能。我无法理解一件事:

defmodule Alex do
  use Included,
    names: [:helen, :rebekka],
    states: [
      %{
        :name => :start
      }, [
        name: :finish
      ]
end

我放置了不同的构造函数(map& keyword)以显示差异。我有一个简单的elixir模块,它返回一个值:

defmodule Included do
  demacro __using__(opts) do
    IO.puts Keyword.get(opts, :names) # => [:helen, :rebekka]
    IO.puts Keyword.get(:states) # => [{:%{}, [line: 8], [name: :start]}, [name: :finish]]
  end
end

为什么我会收到这张奇怪的地图?如何在我的模块中获得法线贴图?

1 个答案:

答案 0 :(得分:1)

你得到的是opts的AST表示,就像传递给宏的任何参数一样。如果您正在使用支持者,那么这些形式恰好采用相同的形式引用一个不带引号的形式:

iex> [name: :finish]
[name: :finish]

iex> quote do: [name: :finish]
[name: :finish]

地图不过,因为它们不属于基本数据类型:

iex> %{name: :finish}
%{name: :finish}

iex> quote do: %{name: :finish}
{:%{}, [], [name: :finish]}

这就是为什么proplists是将选项传递给宏的首选方法。但是,您可以按预期在quote内使用未加引号的地图:

defmodule Included do
  defmacro __using__(opts) do
    quote do
      IO.inspect unquote(opts)
    end
  end
end

defmodule Alex do
  use Included, %{name: :start}
end

这将只是打印

%{name: :start}