Erlang和Elixir,第4部分:控制流

如果说逻辑运算符可能与流行语言之间最常见的相似之处,那么毫无疑问,Elixir也有它们。 提供了ifcasecond宏来为我们提供控制流结构。

对于模式匹配,我们之前提到过,用case可以迭代地匹配任何模式:

iex> checkUser = 'simon'
'simon'

iex> case {checkUser} do
...>      {'simon'} ->
...>           'User Match - Simon'
...>      {'mary'} ->
...>           'User Match - Mary' 
...>      _ ->
...>           'This will match any value.. use as a catch-all'
...> end

'User Match - Simon'

值得一提的是_情况,这实际上是默认的万能情况。 这种情况也可以与atom或类似的任何变量类型一起使用。

iex> case {:user} do
...>      {:user} ->
...>           'User Match'
...>      _ ->
...>           'No match'
...> end

'User Match'

警卫队条款表达

Elixir提供了许多运算符来检入我们的表达式,以防止捕获错误的数据。 默认情况下,支持以下内容:

  • 比较运算符( ==!====!==>>=<<=
  • 布尔运算符( and ornot
  • 算术运算( +-*/
  • 算术一元运算符( +-
  • 二进制串联运算符<>
  • 只要右侧是范围或列表, in操作符
  • 以下所有类型检查功能:
    • is_atom/1
    • is_binary/1
    • is_bitstring/1
    • is_boolean/1
    • is_float/1
    • is_function/1
    • is_function/2
    • is_integer/1
    • is_list/1
    • is_map/1
    • is_nil/1
    • is_number/1
    • is_pid/1
    • is_port/1
    • is_reference/1
    • is_tuple/1
  • 加上以下功能:
    • abs(number)
    • binary_part(binary, start, length)
    • bit_size(bitstring)
    • byte_size(bitstring)
    • div(integer, integer)
    • elem(tuple, n)
    • hd(list)
    • length(list)
    • map_size(map)
    • node()
    • node(pid | ref | port)
    • rem(integer, integer)
    • round(number)
    • self()
    • tl(list)
    • trunc(number)
    • tuple_size(tuple)

我们可以这样使用它们:

iex> case 1 do                     
...>   x when is_number(x) -> "Number #{x}"
...>   x when is_boolean(x) -> "Boolean #{x}"
...> end
"Number 1"

此外,匿名函数可以具有多个防护。 例如,要使用高,低和收盘价从金融市场数据计算枢轴点,我们可以这样做:

iex> pivot = fn
...>         h, l, c when h < l -> "Error"      
...>         h, l, c -> (h + l + c) / 3
...> end
iex> pivot.(1233, 1212, 1226) # Usage: High, Low, Close..
1223.6666666666667

在这里,如果高值小于低值,则数据透视匿名函数将返回错误消息。 这种单行式的写保护非常强大。

条件

switch语句一样,Elixir的cond是我们可以在其中执行类似if的字符串(如块)并在比赛中执行的地方。

iex> cond do
...>   2 + 2 == 5 ->
...>     "This is never true"
...>   2 * 2 == 3 ->
...>     "Nor this"
...>   true ->
...>     "This is always true (equivalent to else)"
...> end
"This is always true (equivalent to else)

cond块中,除nilfalse外,其他所有内容的评估结果均为false 。 那就是所有的数值和字符串。

例如,我们可以使用cond块检查当前状态的各种可能性:

iex> cond do
...>     status == 'available' ->
...>        "User is available"
...>     status == 'busy' ->
...>       "User is busy"
...>     true ->
...>       "No input provided"
...> end

当status的值设置为字符串时,它将求值; 否则,默认情况下将通过最后一个true情况输出错误消息。

如果和除非

Elixir还为我们提供了unless ,这是if else块的默认部分,可以这样演示:

iex> if true do 
...>  'works'
...> end
'works'
iex> unless false do
...> 'other case'
...> end
'other case'

如果if情况的评估结果为true,则unless您可以使用相反的方法。 如所示,我们可以通过这种方式抓住条件的另一面。

在现实生活中的示例中,这可用于在条件提醒(例如提醒或提示)期间显示条件信息。

iex> if t do
...>   'Process information here...'
...> end
nil
iex> unless false do
...>    'Hint to show user when information is not right' 
...> end
'Hint to show user when information is not right'

执行/结束块

在这些示例中,我们已经看到了doend宏的用法。 在结束本节之前,让我们现在仔细看看它们:

iex> if true, do: 1 + 2
3

true之后的逗号是Elixir的常规语法,   其中每个参数用逗号分隔。 此语法使用关键字列表,并且与else宏结合使用时,它将如下所示:

iex> if false, do: :this, else: :that
:that

为了更好地进行开发,我们可以使用do/end块,它不需要逗号即可直接使用:

iex> if true do
...>   a = 1 
...>   a + 10
...> end
11
iex> if true, do: (
...>   a = 1
...>   a + 10
...> )
11

结论

Elixir具有熟悉的if/elsecase控制流结构,并且还具有unlessdo/end块。

我们可以通过使用这些结构控制流来实现任何逻辑。 当将它们与宏,匿名函数和模块结合使用时,将提供大量选项来完成工作。

为了继续阅读该主题,该手册提供了更多有关使用do/end块的其他警告的见解,例如功能范围限制。

翻译自: https://code.tutsplus.com/tutorials/elixir-walkthrough-part-4-control-flow--cms-27638