1

我可以直接在交互式 shell 中编写一个匿名函数,如下所示。

iex> total_bottles_milk = fn total -> total * 2 end  
iex> total_bottles_milk.(2)

但是,如果我写入外部文件并在交互式 shell 中运行,则会显示编译错误。

我的文件名和目录路径是 lib/expense.ex

下面是我的代码

defmodule Expense do

    total_bread_slices = fn total -> (total * 10) / 100 end
    total_bottles_milk = fn total -> total * 2 end
    total_cakes = fn total -> total * 15 end

    def total_expense(bread_slices, bottles_of_milk, cakes) do
        total_bread_slices.(bread_slices) + total_bottles_milk.(bottles_of_milk) + total_cakes.(cakes)
    end

end

当我进入文件夹路径并运行iex -S mix以运行我的费用模块时,终端显示编译错误。
我想知道只有我可以将匿名函数直接运行到交互式外壳中,而不是从外部源运行并编译它。我想把我的功能写成一等公民。如果有办法,我该怎么做?

4

4 回答 4

5

您不能在 elixir 中创建这样的“变量”(参见EDIT 1下文Edit 2)。你看到的错误是正常的。

您可以将匿名函数放入命名函数并从那里调用它们,这会给您相同的结果:

defmodule Expense do

  def total_expense(bread_slices, bottles_of_milk, cakes) do
    total_bread_slices().(bread_slices) + total_bottles_milk().(bottles_of_milk) + total_cakes().(cakes)
  end

  defp total_bread_slices, do: fn total -> (total * 10) / 100 end
  defp total_bottles_milk, do: fn total -> total * 2 end
  defp total_cakes, do: fn total -> total * 15 end
end

这样,您将调用命名函数,该函数将返回匿名函数,然后您将参数传递给该函数。

编辑 1

您不能像 INSIDE 模块那样创建变量。这在 iex 中有效,因为它是一个交互式环境。但是,x = y在 elixir 模块中的函数之外,语法无效。

编辑 2 感谢@Dogbert 的更正。您实际上可以在模块内部和函数外部创建变量,但不能在def.

于 2018-07-10T07:32:00.997 回答
0

感谢@Abdullah Esmail,我可以这样写我的函数

defmodule Expense do

    def total_bread_slices do
        fn total -> (total * 10) / 100 end
    end 

    def total_bottles_milk do
        fn total -> total * 2 end
    end 

    def total_cakes do
        fn total -> total * 15 end
    end 

    def total_expense(bread_slices, bottles_of_milk, no_of_cakes) do

        bread = total_bread_slices()
        milk = total_bottles_milk()
        cakes = total_cakes()

        bread.(bread_slices) + milk.(bottles_of_milk) + cakes.(no_of_cakes)
    end

end
于 2018-07-10T08:54:25.450 回答
0

感谢@Dogbert,如果我想将该函数用作值,这是另一种方法。

首先,我定义了一个命名函数,然后使用 Elixir 的函数捕获运算符&,我可以更轻松地将命名函数用作值。

这样,使用&操作符捕获对函数的引用和=操作符绑定到变量,我可以将命名函数绑定到变量。

defmodule Expense do

    defp total_bread_slices(total) do
        (total * 10) / 100
    end 

    defp total_bottles_milk(total) do
        total * 2 
    end 

    defp total_cakes(total) do
        total * 15 
    end 

    def total_expense(bread_slices, bottles_of_milk, no_of_cakes) do

        bread = &total_bread_slices/1
        milk = &total_bottles_milk/1
        cakes = &total_cakes/1

        bread.(bread_slices) + milk.(bottles_of_milk) + cakes.(no_of_cakes)

    end

end
于 2018-07-11T07:56:30.460 回答
0

在 Elixir In Action 书籍第二版的运行示例中,我遇到了同样的问题。为了避免在 iex 中重新输入 lambda 函数示例,我将它们保存在一个文件中。我试图将它们加载到 iex 中,例如:

iex solutions/ch05.ex

但是当我调用 lambda 函数时:

a_lambda.("something")

我在iex中遇到了编译错误。

现在我将文件中的 lambda 代码直接复制/粘贴到 Iex,它可以工作。

于 2019-08-12T18:10:46.120 回答