【问题标题】:How can I refer to a module variable in a function without referring to its module in Elixir 1.0.3? In its parent scope?如何在 Elixir 1.0.3 中引用函数中的模块变量而不引用其模块?在其父范围内?
【发布时间】:2015-05-04 16:09:58
【问题描述】:

我想让 Elixir 1.0.3 中的函数引用其“父”范围内的变量。在这种情况下,它的父作用域是一个模块。

这与我在上一个问题中使用的代码相同:

defmodule Rec do
  def msgurr(text, n) when n <= 1 do
    IO.puts text
  end

  def msgurr(text, n) do
    IO.puts text
    msgurr(text, n - 1)
  end
end

如果我将其更改为以下内容:

defmodule Rec do
  counter = "done!"
  def msgurr(text, n) when n <= 1 do
    IO.puts text
    IO.puts Rec.counter
  end

  def msgurr(text, n) do
    IO.puts text
    msgurr(text, n - 1)
  end
end

它编译得很好,但是如果我尝试 msgurr 函数,我会收到以下错误:

** (UndefinedFunctionError) undefined function: Rec.counter/0
    Rec.counter()
    recursion_and_import_test.exs:5: Rec.msgurr/2

我还尝试了以下方法:

defmodule Rec do
  counter = "done!"
  def msgurr(text, n) when n <= 1 do
    import Rec
    IO.puts text
    IO.puts Rec.counter
  end

  def msgurr(text, n) do
    IO.puts text
    msgurr(text, n - 1)
  end
end

不过,我在这里收到了编译时警告: ➜ ubuntu elixirc recursiontest.exs recursion_and_import_test.exs:1:警告:重新定义模块 Rec recursion_and_import_test.exs:2:警告:变量计数器未使用 recursion_and_import_test.exs:4:警告:未使用的导入记录

当我尝试使用 msgurr 功能时:

➜ ubuntu iex Erlang/OTP 17 [erts-6.3] [source] [64-bit] [smp:8:8] [async-threads:10] [kernel-poll:false]

Interactive Elixir (1.0.3) - press Ctrl+C to exit (type h() ENTER for help)
iex(1)> import Rec
nil
iex(2)> Rec.msgurr("blah", 3)
blah
blah
blah
** (UndefinedFunctionError) undefined function: Rec.counter/0
    Rec.counter()
    recursiontest.exs:6: Rec.msgurr/2

我似乎无法将我自己的变量从模块导入到该模块内的函数中。

我已经阅读了导入文档,但我似乎无法从中理解如何做这种事情。我应该检查 Erlang 文档吗?

【问题讨论】:

    标签: import module scope elixir


    【解决方案1】:

    您将模块与对象混淆了。

    Rec.counter 
    

    总是指 Rec Module 中的函数。这就是错误消息告诉您的内容,他们找不到该功能。模块不能像你想象的那样有变量。

    模块可以有属性。虽然可能会捏造想要的东西 使用模块属性,如果你想使用 Rec.counter 引用它,你应该只创建一个返回常量的函数。

    def counter do
      "done!"
    end
    

    还有更多关于模块属性here,但是如果你想能够在灵丹妙药中思考,你需要开始思考“函数而不是变量”。

    【讨论】:

    • 说到,为什么不只允许变量而不是属性?我缺乏任何类型的函数式编程的经验。这对我来说似乎有点武断,尽管我知道一定有原因。
    • 模块变量意味着可变状态,这打破了函数式编程的原则之一。有很多比我可以在评论中进入的内容。你可能会发现这个线程很有用groups.google.com/forum/?hl=en#!topic/elixir-lang-talk/…
    • 这也是为了避免像 Python 中的 local 这样的事情,你可能会在“模块变量”和函数之一之间发生冲突。消除歧义并引入明确的符号会更简洁,因为它表明意图(即,您使用 @attribute 是因为在某个地方您会需要它)。
    • //,----- BEGIN PGP SIGNATURE -----版本:OpenPGP的over9000 wl4EABEKAAYFAlV0wwAACgkQfOj8ab4RgiI0ygD + OA8XB9fv4AZOttQS4sJzOjd / r3xTN2V + kdTTndrkQ4EA / A2B + 6 + 24V / u0TEll6Mjlaq2FNhtQ5ZTFIjfF2O9a / P1 = SZgw --- --END PGP签名-----
    猜你喜欢
    • 1970-01-01
    • 2013-12-08
    • 2019-12-12
    • 1970-01-01
    • 2015-04-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多