Erlang 从零 · 第 15 课(展开目录)
01 · 先打开 erl02 · 先认常见 term03 · 分清两种文字04 · 变量只接一次05 · 拆开一列,再筛一次06 · 把文字安全变成整数07 · 用 case 选一条路08 · 让函数继续走09 · 把代码放进模块10 · 条件必须说真话11 · 一层一层取数据12 · 文字先说清编码13 · 让函数子句排好队14 · 带着累加器往前走15 · 先看值,再选路16 · 给模块立规矩17 · 让 rebar3 管项目18 · 让结果有固定形状19 · 把磁盘当成会失败的邻居20 · 把函数交给 list21 · record 留在院里22 · 先写模块之间的约定23 · 把 term 形状写出来24 · 小测试与整段路25 · 把应用磨成命令26 · 先把小项目圈住27 · 把真实文件洗干净28 · 公开入口越少越稳29 · 把约定留在源码旁30 · 打包,也留下线索31 · 按最初任务交卷
ERLANG · 基础 · LESSON 1535 分钟

先看值,再选路

用 `case` 匹配结果,用 `if` guard 选择第一条真条件。

01 · 先看完整例子

先解析,再分类

把输入改为 <<"thirteen">>,观察错误原样返回。

Erlang
ParseAge =
  fun(Text) ->
    case string:to_integer(Text) of
      {Age, <<>>} -> {ok, Age};
      _ -> {error, bad_age}
    end
  end,

%% 只在解析成功时进入年龄分类
case ParseAge(<<"13">>) of
  {ok, Age} when Age < 12 -> {ok, child};
  {ok, _Age} -> {ok, teen_or_adult};
  Error -> Error
end.
先对照结果
  • <<"13">> 得到 {ok,teen_or_adult}。
  • 无效文字得到 {error,bad_age}。
02 · 回头拆代码

从第一行往下读

  1. string:to_integer/1 返回整数与剩余文字,或 {error, Reason}。
  2. 解析函数把各种失败统一为 {error,bad_age}。
  3. 外层 case 只负责年龄业务分支。
03 · 认清新符号

符号不是暗号

case Value of

开始按值匹配分支。

if

开始按 guard 条件选择。

end

结束 case、if、try 或 fun 等结构。

04 · 代码里的概念

把名字和意思对上

01

case 表达式

计算一个值,再选择第一条匹配子句。

02

if 表达式

从上到下选择第一条 guard 为 true 的分支。

05 · 再说清楚

这些写法为什么有用

Erlang 最常见的选择来自模式匹配。函数子句能解决时,先用函数子句;局部结果再用 case。

case 按一个值的形状选分支。if 实际按 guard 选择,最后常写 true -> 作为兜底。

不要把所有逻辑塞进深层嵌套。先把底层结果整理成稳定 tuple,下一层会更好读。

06 · 自己改一次

合上答案,动手

让空 list 返回 empty,非空 list 返回第一项。

练习起点
case [8, 9] of
  ____ -> empty;
  [Head | _] -> ____
end.

目标结果: 得到 8。

卡住了,再看提示

空 list 是 [];第二处返回 Head。

运行过以后,再看一种答案
一种答案
case [8, 9] of
  [] -> empty;
  %% 非空 list 的 Head 是第一项
  [Head | _] -> Head
end.
想一想:Erlang 的 `if` 是否一定比 `case` 更适合所有条件判断?

不是。if 只看 guard;若已经有一个结果要按形状拆开,case 更直接。

带走

记住三句

  1. 1

    优先用模式表达数据分支。

  2. 2

    case 看值形状,if 看 guard。

  3. 3

    底层结果先整理,再做业务判断。

本课结束代码也跑过一次,就把这一课收好。