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,我发现此代码产生了意外的结果: defmodule Foo do defmodule Foo.Bar do def test1 do IO.inspect Foo.Baz end def test2 do IO.inspect Other.Baz end end end > Foo.Foo.Bar.test1 Foo.Foo.Baz > Foo.Foo.Bar.test2 Other.Baz 我希望测试至少能产生一致的

我发现此代码产生了意外的结果:

defmodule Foo do
  defmodule Foo.Bar do
    def test1 do
      IO.inspect Foo.Baz
    end
    def test2 do
      IO.inspect Other.Baz
    end
  end
end
> Foo.Foo.Bar.test1
Foo.Foo.Baz
> Foo.Foo.Bar.test2
Other.Baz
我希望测试至少能产生一致的结果,比如:

# Both have a namespace of Foo
> Foo.Foo.Bar.test1
Foo.Foo.Baz
> Foo.Foo.Bar.test2
Foo.Other.Baz
# or
# Neither has a namespace of Foo
> Foo.Foo.Bar.test1
Foo.Baz
> Foo.Foo.Bar.test2
Other.Baz
但是意外的结果显示它依赖于模块名称的前缀(
Foo.Bar
&
Foo.Baz
,在test1中),这让我感到惊讶

更新:

由于@mudasobwa的回答,我意识到还有另一个问题

对于这种情况,我们知道
B
应该是
A.B
,因为我们想直接使用
B

defmodule A do
  defmodule B do
    def test do
      IO.inspect B
    end
  end
end
> A.B.test
A.B
但是,为什么
B
仍然
A.B

defmodule A do
  defmodule B.C do
    def test do
      IO.inspect B
    end
  end
end
> A.B.C.test
A.B

Foo.Baz
Other.Baz
都是原子。仅仅是简单的原子,能够用漂亮的圆点和大写字母来书写它们,这就是语法上的糖分。尝试打开
IEx
,不加载任何内容,只需键入:

iex(1)> i Foo.Baz
结果是:
IEx
知道它,它是一个原子:

iex(1)> i Foo.Baz

Term
  Foo.Baz
Data type
  Atom
Reference modules
  Atom
也就是说,你输出了原子,它们被成功地输出了。它们看起来与模块名称相似的事实是一种情况


但由于这是作为一个模块名表示,Elixir尽量“解决”这些问题。作为“内部模块”,可以从其他模块函数内部调用模块函数,而无需在其前面加上模块名称:

defmodule A do
  def a, do: IO.puts "Hello"
  def b, do: a  # ⇐ this
end
当从
a.b
调用时,
a
隐式解析为
a.a
。嵌入式/嵌套模块也会发生同样的情况:

defmodule A do
  defmodule B do
    def a, do: IO.puts "Hello"
    def b, do: B.a  # ⇐ this
  end
end
为了使这个
B.a
调用成为可能,
B.a
实际上被解析为
a.B.a
,这是可能的,因为
B
本身内部被解析为
a.B


您看到的是原子到模块名称外推的一个缺点。

我认为这与OP的问题无关。@Dogbert确实,谢谢,出于某种原因,昨天我公布了一半的答案;我原以为它说得很清楚,但现在我重读了一遍,并更新了解释。谢谢你的回答!但我想到了与此相关的另一个问题。我已经更新了这个问题。
B
显然被解析为
A.B
,因为它被解析为完整的限定模块名,而不是“this”,或者您所期望的
B
在该上下文中是
A.B
。恐怕我不明白你期望在那里看到什么。我理解你的例子。但以我的例子
A.B.C.test
,我认为
B.C
是一个整体,所以我
B
不应该是
A.B
。然而,从结果来看,我的想法是完全错误的。