Back

elixir - 8.module, function, fn

发布时间: 2019-02-17 09:36:00

参考:https://elixir-lang.org/getting-started/modules-and-functions.html

定义一个module, 和 function

defmodule Math do 
  def sum(a,b) do 
    a + b
  end
end


{:module, Math,
<<70, 79, 82, 49, 0, 0, 4, 64, 66, 69, 65, 77, 65, 116, 85, 56, 0, 0, 0, 124,
0, 0, 0, 14, 11, 69, 108, 105, 120, 105, 114, 46, 77, 97, 116, 104, 8, 95,
95, 105, 110, 102, 111, 95, 95, 7, 99, ...>>, {:sum, 2}}

iex(2)> Math.sum(3,5)
8

然后,可以进行编译:

$ elixirc math.ex

会发现出现了一个新文件:Elixir.Math.beam

可以在 iex中直接调用:

iex> Math.sum(3,5)  

8

.ex文件: 需要编译,才能运行

.exs: 直接运行(script 模式)

例如:

defmodule MyMath do 
  def sub(a,b) do
    a - b
  end
end

IO.puts MyMath.sub(5,3)

$ elixir math_script.exs
2

可以使用defp来定义私有方法。 私有方法是无法被调用的。 

还可以定义同名方法,带不同的参数:

defmodule MathTwo do
  def zero?(0) do 
    true
  end
  def zero?(x) when is_integer(x) do
    false
  end
end

IO.puts MathTwo.zero?(0)

elixir math_two.exs #=> true

上面的方法等同于:

defmodule MathTwo do
  def zero?(0), do: true
  def zero?(x) when is_integer(x), do: false
end

我们可以对上面的zero?方法进行引用。

$ iex math_two.exs

> a = MathTwo.zero?/1     # 这里的1表示 /arity, 就是参数的个数。  a  是captured function, 也是anonymous function

> a.(0)   # true               #  调用 匿名函数的时候, 需要用 .(para) 来调用

>a.(100) # false

我们也可以对 is_function, is_integer 等这些看不到 module的方法,进行  capture (符号就是 & )

iex(10)> &is_function/1
&:erlang.is_function/1
iex(11)> c = &is_function/1
&:erlang.is_function/1
iex(12)> c.(a)
true

我们还可以使用& 来快速的定义方法:   &1 表示第一个参数。 &(...) 则等同于: def ... end 的方法体

iex(13)> fun = &(&1 + 3)    #  等同于:  fn x -> x + 3 end 
#Function<6.128620087/1 in :erl_eval.expr/5>
iex(14)> fun.(4)
7
iex(15)> fun2 = &"hi #{&1}"
#Function<6.128620087/1 in :erl_eval.expr/5>
iex(16)> fun2.("Jim")
"hi Jim"

使用fn 声明一个匿名函数:

iex(17)> c = fn x -> x+3 end

#Function<6.128620087/1 in :erl_eval.expr/5>
iex(18)> c.(5)
8

使用 \\ 来表示默认参数:

defmodule DefaultTest do
  def hi(x \\ "lala") do
    x
  end
end

IO.puts DefaultTest.hi               # => lala
IO.puts DefaultTest.hi("Jim")    # => Jim

对于存在多个参数的多个默认值的实现:

defmodule MyConcat do

  # 存在多个默认值的话,需要这样的声明(注意方法体省略了)
  def join(a, b \\ nil, separator \\ " ")

  # 这个要写在前面
  def join(a, b, _separator) when is_nil(b) do
    a
  end

  # 这个方法的实现写在后面,用来兜底
  def join(a, b, separator) do 
    a <> separator <> b
  end


end

# 所有的参数都具备
IO.puts MyConcat.join("good", "morning", "+")    # good+morning
IO.puts MyConcat.join("good", "morning")         # good morning
IO.puts MyConcat.join("lalala")                  # lalala

Back