Erlang 从零 · 第 04 课(展开目录)
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 0425 分钟
变量只接一次
认识大写变量、单次赋值和模式匹配。
01 · 先看完整例子
左边是形状,右边是数据
map 的创建使用 =>,模式匹配已有 key 时使用 :=。
Erlang
%% 先清掉 shell 中已有的变量绑定
f().
%% 标签 ok 必须对上,Score 接住 92
{ok, Score} = {ok, 92}.
%% map 模式取值,再核对已绑定变量
#{name := Name} = #{name => <<"A-Qing">>, age => 12}.
92 = Score.
{Score, Name}.先对照结果
Score绑定到92。Name绑定到<<"A-Qing">>。- 最后得到
{92, <<"A-Qing">>}。
02 · 回头拆代码
从第一行往下读
{ok, Score}要求右边是两个元素的 tuple,而且第一个必须是 atomok。#{name := Name}是 map 模式。它寻找已有 keyname,让Name接住对应值。92 = Score能成功,因为Score已经是 92;写93 = Score会badmatch。
03 · 认清新符号
符号不是暗号
Name大写开头,是变量。
name小写开头,是 atom。
_匹配这个位置,但不保存它的值。
f().只在 Erlang shell 使用:清掉当前 shell 里已有的变量绑定。
04 · 代码里的概念
把名字和意思对上
变量
以大写字母或下划线开头的名字,如 Name、_Rest。
单次赋值
一个变量接住值后,在当前作用域中不能改成另一个值。
匹配
检查左右形状,并让新变量接住对应位置的值。
05 · 再说清楚
这些写法为什么有用
Erlang 变量必须以大写字母或下划线开头。Score 是变量,score 是 atom。
变量在一次匹配中接住值后,不能再改绑到另一个值。这叫单次赋值。
= 是匹配运算符。左边写形状,右边给数据;形状对不上时会出现 badmatch。
设计选择
为什么这样写
为什么不把 = 只当作赋值?
模式把“检查形状”和“取出数据”合在一次操作里。函数入口、case 和 receive 因此能用同一套读法。
跨一次新的匹配时,两门语言规则不同:Elixir 的名字默认可以重新绑定,要用 ^name 才核对旧值;Erlang 的变量一旦绑定,再出现在模式里就会核对。
换一把尺子
从 Java、Python、JavaScript 看过来
Java
- 熟悉的起点
- 局部变量赋值,再用 getter 或 instanceof 检查对象。
- BEAM 在意什么
- 模式直接检查 tuple、list 或 map 的形状并取值。
- 别带错直觉
- 这里不是方法重载,也不会修改右边的数据。
Python
- 熟悉的起点
- 解包和 match/case 已有相近感觉。
- BEAM 在意什么
- 数据不会被原地改写,模式也是函数子句和消息协议的日常工具。
- 别带错直觉
- Elixir 可以重新绑定名字,但不会改掉原值;Erlang 的已绑定变量会用来核对。
JavaScript
- 熟悉的起点
- 数组、对象解构主要负责取值。
- BEAM 在意什么
- BEAM 模式还会核对固定标签;不匹配会走别的子句或失败。
- 别带错直觉
- 对象解构的默认值与 BEAM 模式不是同一套规则。
06 · 自己改一次
合上答案,动手
从 {weather, <<"Xi'an">>, 28} 中拆出城市和温度。
练习起点
%% 清掉示例和前几课留下的变量
f().
%% 固定标签必须对上,变量用大写开头
{____, ____, ____} = {weather, <<"Xi'an">>, 28}.
%% 查看拆出的值
{City, Temperature}.目标结果: 得到 {<<"Xi'an">>, 28}。
卡住了,再看提示
左边依次写 atom weather、变量 City、变量 Temperature。
运行过以后,再看一种答案
一种答案
%% f() 只属于 shell,不要写进 .erl 文件
f().
%% atom 核对标签,变量接住数据
{weather, City, Temperature} = {weather, <<"Xi'an">>, 28}.
%% 变量已经分别绑定
{City, Temperature}.想一想:已经执行 `Count = 3.` 后,再执行 `Count = 4.` 会怎样?
会出现 badmatch。Count 已绑定到 3,不能再接住不同的值 4。
带走
记住三句
- 1
大写开头是变量,小写开头通常是 atom。
- 2
Erlang 变量一旦绑定就不能改值。
- 3
=会进行模式匹配。
本课结束代码也跑过一次,就把这一课收好。