Elixir 中函数调用的思考
开始使用 Elixir 以来,对于函数调用的方式有了很多的想法,比如利用 Elixir 中的 pipeline 和函数调用写一个简单的例子:
defmodule Demo do
defstruct [:one, :two, :three]
def work(struct, fun \\ &(&1)) do
fun.(struct)
end
end
Demo
|> struct(%{})
|> work(&(%{&1 | one: :done}))
|> work(&(%{&1 | two: :done}))
|> work(&(%{&1 | three: :done}))
得益于 Elixir 中函数的 & 表示法,在写出简洁优雅的程序的同时,功能也异常强大。接下来我们就利用这些函数特性来实现更多的功能:
1. 使 [1, 2, 3] 通过一个函数调用实现 [1+3, 2+5, 3+8] 的效果
其实也就是实现 List 中每个元素调用不同的函数:
def zip(vars, funs) do
unless length(vars) == length(funs) do
raise "Variable list and function list should have the same length"
end
fun_var_list = Enum.zip(vars, funs)
Enum.map fun_var_list, fn({var, fun}) -> fun.(var) end
end
zip([1,2,3], [&(&1+3), &(&1+5), &(&1+8)])
2. 使 fn([1, 2, 3]) 实际调用 fn(1, 2, 3)
这个和 Ruby 中的 * 解构操作有点类似,即接受 List 参数,转变为多个参数, 在 Elixir 中我们使用 apply 来达到该功能
def splicing(vars, fun) do
apply(fun, vars)
end
3....