elixir官方入门教程 case,cond和if 您所在的位置:网站首页 elixir学习 elixir官方入门教程 case,cond和if

elixir官方入门教程 case,cond和if

2023-08-15 02:48| 来源: 网络整理| 查看: 265

为什么80%的码农都做不了架构师?>>>   hot3.png

#case,cond和if

1. `case` 2. 卫语句中的表达式 3. `cond` 4. `if`和`unless` 5. `do/end`块

本章,我们将学习case,cond和if控制流结构。

#case

case允许我们将一个值与多个模式进行匹配,直到匹配成功:

iex> case {1, 2, 3} do ...> {4, 5, 6} -> ...> "This clause won't match" ...> {1, x, 3} -> ...> "This clause will match and bind x to 2 in this clause" ...> _ -> ...> "This clause would match any value" ...> end "This clause will match and bind x to 2 in this clause"

如果你想对已存在的变量进行模式匹配,你需要使用^操作符:

iex> x = 1 1 iex> case 10 do ...> ^x -> "Won't match" ...> _ -> "Will match" ...> end "Will match"

卫语句中允许包含额外的条件:

iex> case {1, 2, 3} do ...> {1, x, 3} when x > 0 -> ...> "Will match" ...> _ -> ...> "Would match, if guard condition were not satisfied" ...> end "Will match"

第一条语句在x是正数时才能匹配。

#卫语句中的表达式

Elixir默认在卫语句中可以使用以下表达式:

- 比较运算符(==,!=,===,!==,>,>=, case 1 do ...> x when hd(x) -> "Won't match" ...> x -> "Got: #{x}" ...> end "Got 1"

如果没有语句匹配到,会抛出一个错误:

iex> case :ok do ...> :error -> "Won't match" ...> end ** (CaseClauseError) no case clause matching: :ok

注意匿名函数也可以拥有多个卫语句:

iex> f = fn ...> x, y when x > 0 -> x + y ...> x, y -> x * y ...> end #Function iex> f.(1, 3) 4 iex> f.(-1, 3) -3

匿名函数的分语句中参数的数量应当相同,否则会抛出错误。

iex> f2 = fn ...> x, y when x > 0 -> x + y ...> x, y, z -> x * y + z ...> end ** (CompileError) iex:1: cannot mix clauses with different arities in function definition

#cond

当你想要匹配不同的值时可以用case。然而,我们有时想要检查不同的情形并找出其中第一个结果为真的。这时,我们可以使用cond:

iex> cond do ...> 2 + 2 == 5 -> ...> "This will not be true" ...> 2 * 2 == 3 -> ...> "Nor this" ...> 1 + 1 == 2 -> ...> "But this will" ...> end "But this will"

这和许多命令语言中的else if从句是一样的(虽然在这里不经常用到)。

如果没有一种情况返回为真,则抛出一个错误(CondClauseError)。所以,有必要在最后加上一个等于true的最终情况:

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会将任何不是nil或false的值认为真:

iex> cond do ...> hd([1, 2, 3]) -> ...> "1 is considered as true" ...> end "1 is considered as true"

#if和unless

除了case和cond,Elixir也提供了if/2和unless/2这两个宏,让你在只需要检查一种情况时使用:

iex> if true do ...> "This works!" ...> end "This works!" iex> unless true do ...> "This will never be seen" ...> end nil

如果传送给if/2的情况返回值是false或nil,do/end中的代码就不会执行并只返回nil。unless/2正相反。

它们也支持else块:

iex> if nil do ...> "This won't be seen" ...> else ...> "This will" ...> end "This will"

注意:在这里if/2和unless/2是被当作宏来执行的;而非其它许多语言中一样作为特殊的结构体。你可以在Kernel模块文档中查看说明文档和if/2的源代码。Kernel模块中定义了诸如+/2之类的操作符和'if_function/2`之类的函数,它们全都默认自动导入并在你的代码中可用。

#do/end块

目前,我们已经学习了四种控制结构:case,cond,if和unless,它们都包含了do/end块。所以我们也能够以如下方式写if语句:

iex> if true, do: 1 + 2 3

注意在true和do:之间有一个逗号,这是因为Elixir中参数之间要以逗号隔开。我们称这种格式为关键字列表。我们也可以用关键字来传递else:

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

do/end块形式是在关键字形式的语法上经过化简所得的。这就是为什么do/end块形式不要求参数与块之间用逗号隔开。它消除了在书写块代码时的冗余信息。下列两种语法作用是相同的:

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

需要记住的是在使用do/end块时,它们总是和最外层的函数调用捆绑在一起。例如:

iex> is_number if true do ...> 1 + 2 ...> end ** (CompileError) undefined function: is_number/2

会被解释成:

iex> is_number(if true) do ...> 1 + 2 ...> end ** (CompileError) undefined function: is_number/2

产生错误的原因是Elixir试图调用is_number/1函数,却得到了两个参数(if true表达式也会产生错误,因为if需要它的第二个参数,也就是do/end块)。添加明确的括号能够消除歧义:

iex> is_number(if true do ...> 1 + 2 ...> end) true

关键字列表在语言中扮演着重要的角色,在许多函数与宏中都很常见。在之后的章节中我们会继续他;探索它。现在,让我们谈谈“二进制,字符串和字符列表”。



【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

      专题文章
        CopyRight 2018-2019 实验室设备网 版权所有