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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/batch-file/6.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
Macros 在宏中定义和使用函数_Macros_Elixir - Fatal编程技术网

Macros 在宏中定义和使用函数

Macros 在宏中定义和使用函数,macros,elixir,Macros,Elixir,下面这个例子: defmodule Greetify do defmacro __using__(_) do quote do Module.register_attribute __MODULE__, :greet, accumulate: true, persist: false @before_compile Greetify end end defmacro __before_compile__(env) do

下面这个例子:

defmodule Greetify do

  defmacro __using__(_) do
    quote do
      Module.register_attribute __MODULE__, :greet, accumulate: true,
        persist: false
      @before_compile Greetify
    end
  end

  defmacro __before_compile__(env) do
    greetings = Module.get_attribute(env.module, :greet)
    for {name, age} <- greetings do
      IO.puts "#{name} is #{age} years old"
    end
  end

end
defmodule Greetify do
定义宏\uuuuuu使用\uuuu(\uu)do
引述
Module.register\u属性\uuuuu Module\uuuuu,:问候,累计:true,
坚持:错
@在你开始贪婪之前
结束
结束
在编译之前定义宏
问候语=Module.get_属性(env.Module,:问候语)

对于{name,age}嗯,这是可能的。代码的问题在于混合了作用域。Elixir中的宏在编译阶段被扩展。此时此刻没有编译的
say_greetings/1
函数(除此之外,不能从
defmacro
内部调用
defp
,但这可以通过适当的引用来克服。)

要使其工作,您需要在编译之前,在与
\u相同的范围内声明
说问候语/1
,以使其可用。您不能将其定义为函数(见上文),但解决方法是将其定义为宏。这样,它将在编译过程中进行扩展,所有内容都将正常工作(同时,我怀疑我是否理解这样做的原因。)

总结如下:

defmodule Greetify do
定义宏\uuuuuu使用\uuuu(\uu)do
引述
Module.register\u属性\uuuuu模块\uuuuu,:问候、累积:真、持续:假
@在你开始贪婪之前
结束
结束
说问候语(问候语)做什么
引述

对于{name,age}嗯,这是可能的。代码的问题在于混合了作用域。Elixir中的宏在编译阶段被扩展。此时此刻没有编译的
say_greetings/1
函数(除此之外,不能从
defmacro
内部调用
defp
,但这可以通过适当的引用来克服。)

要使其工作,您需要在编译之前,在与
\u相同的范围内声明
说问候语/1
,以使其可用。您不能将其定义为函数(见上文),但解决方法是将其定义为宏。这样,它将在编译过程中进行扩展,所有内容都将正常工作(同时,我怀疑我是否理解这样做的原因。)

总结如下:

defmodule Greetify do
定义宏\uuuuuu使用\uuuu(\uu)do
引述
Module.register\u属性\uuuuu模块\uuuuu,:问候、累积:真、持续:假
@在你开始贪婪之前
结束
结束
说问候语(问候语)做什么
引述

对于{name,age}谢谢你的回答,是的,我知道它们是编译的,这就是为什么我认为它可以使用before_compile宏。例如,如果我必须使用几个函数而不仅仅是“say_问候语”,那么它们都必须是一个单独的宏,对吗?为了在未编译宏之前在编译范围内可用,在编译之前将它们扩展到AST inplace,这就是为什么在编译开始之前可以访问它们。老实说,除了将它们放入单独的宏中之外,我无法发明其他解决方案,但我不确定这是否不可能以其他方式实现,但可以像您所说的那样在宏中使用适当的引号调用def?是的,但无法执行尚未编译的函数。您可以声明它,是的,但不能调用。谢谢您的回答,是的,我知道它们是编译的,这就是为什么我认为它可以使用before_compile宏。例如,如果我必须使用几个函数而不仅仅是“say_问候语”,那么它们都必须是一个单独的宏,对吗?为了在未编译宏之前在编译范围内可用,在编译之前将它们扩展到AST inplace,这就是为什么在编译开始之前可以访问它们。老实说,除了将它们放入单独的宏中之外,我无法发明其他解决方案,但我不确定这是否不可能以其他方式实现,但可以像您所说的那样在宏中使用适当的引号调用def?是的,但无法执行尚未编译的函数。你可以申报,可以,但不能打电话。
  defmacro __before_compile__(env) do
    greetings = Module.get_attribute(env.module, :greet)
    say_greetings(greetings)

    defp say_greetings(grettings) do
      for {name, age} <- greetings do
        IO.puts "#{name} is #{age} years old"
      end
    end
  end