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 来自_中嵌套的use语句的别名,使用___Elixir - Fatal编程技术网

Elixir 来自_中嵌套的use语句的别名,使用__

Elixir 来自_中嵌套的use语句的别名,使用__,elixir,Elixir,假设我有一个模块App.a,它有以下代码 defmodule App.A do defmacro __using__(_) do quote do alias App.B end end end 因此,当使用时,它会自动为App.B添加别名 现在,还有另一个模块名为App.C,定义如下: defmodule App.C do defmacro __using__(_) do quote do use App.A def

假设我有一个模块
App.a
,它有以下代码

defmodule App.A do
  defmacro __using__(_) do
    quote do
      alias App.B
    end
  end
end
因此,当使用
时,它会自动为
App.B
添加别名

现在,还有另一个模块名为App.C
,定义如下:

defmodule App.C do
  defmacro __using__(_) do
    quote do
      use App.A

      def foo do
        B.bar()
      end
    end
  end
end
它添加了一个函数
foo
,该函数尝试从模块
B
调用函数,而不显式调用 别名,因为我希望使用
App.A
已经定义了别名

现在,问题是当我有一些其他模块时,比如
App.D
,它
使用
App.C
, 编译将给我一个警告,说明B未定义,因此alias无法工作


有人能解释一下为什么会发生这种情况吗?

别名在使用它们的范围内是局部的。在调用模块的函数中执行使用宏的
\uuu的
quote
块,因此别名有效。但是,当调用
使用App.C
时,别名不在该范围内,因此调用B.bar()将失败

您可以将
App.C
更改为:

defmodule App.C do
  defmacro __using__(_) do
    quote do
      use App.A

      IO.inspect B == App.B # false
      alias App.B
      IO.inspect B == App.B # true

      def foo do
        B.bar()
      end
    end
  end
end
您会注意到,只要别名存在于c.ex中,它就可以工作。在使用之前,您可以在文件中的任何位置定义它:

alias App.B
defmodule App.C do
  # alias App.B
  defmacro __using__(_) do
    # alias App.B
    quote do
      use App.A 
      # alias App.B

      def foo do
       # alias App.B
        B.bar()
      end
    end
  end
end