Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/elixir/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
elixir在宏中定义动态函数_Elixir - Fatal编程技术网

elixir在宏中定义动态函数

elixir在宏中定义动态函数,elixir,Elixir,我试图在defmacro中动态定义函数,但无法理解函数值在函数本身中不可用的原因 defmacro __using__(_) do Enum.each ~w(public private), fn value -> def unquote(:"make_#{value}")(user = %User{}) do %{user | privacy: value} end end end Elixir在默认情况下将value扩展为value(),然后表示

我试图在
defmacro
中动态定义函数,但无法理解函数值在函数本身中不可用的原因

defmacro __using__(_) do
  Enum.each ~w(public private), fn value ->
    def unquote(:"make_#{value}")(user = %User{}) do
       %{user | privacy: value}
    end
  end
end

Elixir在默认情况下将
value
扩展为
value()
,然后表示没有此类功能

您在
def
周围缺少
引号
。您还需要在
def
内的映射更新表达式中取消引用该值。最后,您需要在此处使用
Enum.map
,而不是
Enum.each
,以便
\uuuuuuuuuuuuuuuuuuu using\uuuuu1
返回构建的AST:

defmacro __using__(_) do
  Enum.map ~w(public private), fn value ->
    quote do
      def unquote(:"make_#{value}")(user = %User{}) do
        %{user | privacy: unquote(value)}
      end
    end
  end
end
测试:


编辑:评论中请求的更改:

defmacro __using__(_) do
  Enum.map ~w(public private), fn value ->
    quote do
      def unquote(:"make_#{value}")(user = %User{}) do
        %{user | privacy: unquote(value)}
      end
      def unquote(:"make_#{String.upcase(value)}")(user = %User{}) do
        %{user | privacy: unquote(String.upcase(value))}
      end
    end
  end
end

您在
def
周围缺少一个
quote
。您还需要在
def
内的映射更新表达式中取消引用该值。最后,您需要在此处使用
Enum.map
,而不是
Enum.each
,以便
\uuuuuuuuuuuuuuuuuuu using\uuuuu1
返回构建的AST:

defmacro __using__(_) do
  Enum.map ~w(public private), fn value ->
    quote do
      def unquote(:"make_#{value}")(user = %User{}) do
        %{user | privacy: unquote(value)}
      end
    end
  end
end
测试:


编辑:评论中请求的更改:

defmacro __using__(_) do
  Enum.map ~w(public private), fn value ->
    quote do
      def unquote(:"make_#{value}")(user = %User{}) do
        %{user | privacy: unquote(value)}
      end
      def unquote(:"make_#{String.upcase(value)}")(user = %User{}) do
        %{user | privacy: unquote(String.upcase(value))}
      end
    end
  end
end

但是如果我需要添加更多的函数到与动态生成的
def
相同的级别,该怎么办?您可以将任意数量的
def
放在
quote
中。问题是
\u使用
函数需要一个AST定义列表,因此,如果我声明多个
quote
,则只取最后一个。我不确定我是否遵循。我编辑的答案是否符合您的要求?@Dogbert一个简短的问题:使用
Enum.map
返回的值是引用函数定义的列表。这将插入到调用模块中。它定义了功能吗?Quoted list是列表本身,但它是否意味着编译器执行每个元素,所以定义了函数?但是如果我需要添加更多的函数到动态生成的
def
的同一级别怎么办?您可以在
引号内放置任意数量的
def
。问题是
\u使用
函数需要一个AST定义列表,因此,如果我声明多个
quote
,则只取最后一个。我不确定我是否遵循。我编辑的答案是否符合您的要求?@Dogbert一个简短的问题:使用
Enum.map
返回的值是引用函数定义的列表。这将插入到调用模块中。它定义了功能吗?Quoted list是列表本身,但它是否意味着编译器执行每个元素,从而定义函数?
iex(1)> %User{} |> B.make_public
%User{privacy: "public"}
iex(2)> %User{} |> B.make_PUBLIC
%User{privacy: "PUBLIC"}
iex(3)> %User{} |> B.make_private
%User{privacy: "private"}
iex(4)> %User{} |> B.make_PRIVATE
%User{privacy: "PRIVATE"}