在外部 .ex 文件中编写的 Elixir 匿名函数不能 运行 与交互式 shell
Elixir's anonymous function written in external .ex file can't run with interactive shell
我可以像下面这样直接在交互中写一个匿名函数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
到 运行 我的 Expense 模块时,终端显示编译错误。
我想知道我只能 运行 匿名函数直接进入交互式 shell 而不是从外部来源编译它。我想将我的函数编写为第一个 class 公民。如果有办法,我该怎么做?
您不能在 elixir 中像这样创建 "variables"(请参阅下面的 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
通过这种方式,您将调用命名函数,该函数将 return 匿名函数,然后您将参数传递给该匿名函数。
编辑 1
您不能像 INSIDE 模块那样创建变量。这在 iex 中有效,因为它是一个交互式环境。但是,x = y
语法在 elixir 模块中的函数外部无效。
编辑 2
感谢@Dogbert 的更正。您实际上可以在模块内部和函数外部创建变量,但不能在 def
.
内部使用它们
感谢@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
感谢@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
我在 Elixir In Action 书第二版的 运行 示例中遇到了同样的问题。为了避免在 iex 中重新输入 lambda 函数示例,我将它们保存在一个文件中。我试图在 iex 中加载它们,例如:
iex solutions/ch05.ex
但是当我调用 lambda 函数时:
a_lambda.("something")
我在 iex 中遇到编译错误。
现在我 copy/paste 从文件直接到 Iex 的 lambda 代码,它工作了。
我可以像下面这样直接在交互中写一个匿名函数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
到 运行 我的 Expense 模块时,终端显示编译错误。
我想知道我只能 运行 匿名函数直接进入交互式 shell 而不是从外部来源编译它。我想将我的函数编写为第一个 class 公民。如果有办法,我该怎么做?
您不能在 elixir 中像这样创建 "variables"(请参阅下面的 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
通过这种方式,您将调用命名函数,该函数将 return 匿名函数,然后您将参数传递给该匿名函数。
编辑 1
您不能像 INSIDE 模块那样创建变量。这在 iex 中有效,因为它是一个交互式环境。但是,x = y
语法在 elixir 模块中的函数外部无效。
编辑 2
感谢@Dogbert 的更正。您实际上可以在模块内部和函数外部创建变量,但不能在 def
.
感谢@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
感谢@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
我在 Elixir In Action 书第二版的 运行 示例中遇到了同样的问题。为了避免在 iex 中重新输入 lambda 函数示例,我将它们保存在一个文件中。我试图在 iex 中加载它们,例如:
iex solutions/ch05.ex
但是当我调用 lambda 函数时:
a_lambda.("something")
我在 iex 中遇到编译错误。
现在我 copy/paste 从文件直接到 Iex 的 lambda 代码,它工作了。