Erlang模式匹配基础 #
一、模式匹配概述 #
模式匹配是Erlang的核心特性之一,用于将模式与数据进行匹配,并从中提取信息。
1.1 模式匹配的作用 #
- 变量绑定
- 数据解构
- 条件判断
- 函数分派
1.2 匹配操作符 #
Erlang使用 = 作为匹配操作符:
erlang
-module(match_operator).
-export([demo/0]).
demo() ->
X = 10,
io:format("X = ~p~n", [X]),
{A, B} = {1, 2},
io:format("A = ~p, B = ~p~n", [A, B]),
ok.
注意:= 不是赋值,而是模式匹配!
二、基本模式匹配 #
2.1 变量匹配 #
erlang
-module(var_match).
-export([demo/0]).
demo() ->
X = 10,
10 = X,
io:format("X = ~p~n", [X]),
ok.
2.2 单次赋值 #
erlang
-module(single_assign).
-export([demo/0]).
demo() ->
X = 10,
io:format("X = ~p~n", [X]),
ok.
2.3 匹配失败 #
erlang
-module(match_fail).
-export([demo/0]).
demo() ->
X = 10,
try
20 = X
catch
error:badmatch ->
io:format("Match failed!~n")
end,
ok.
三、原子模式 #
3.1 精确匹配 #
erlang
-module(atom_match).
-export([demo/0]).
demo() ->
ok = ok,
error = error,
io:format("Atom match succeeded~n"),
ok.
3.2 函数返回值匹配 #
erlang
-module(return_match).
-export([demo/0]).
demo() ->
{ok, Result} = some_function(),
io:format("Result: ~p~n", [Result]),
ok.
some_function() -> {ok, 42}.
3.3 错误处理模式 #
erlang
-module(error_pattern).
-export([handle/1]).
handle({ok, Data}) ->
io:format("Success: ~p~n", [Data]);
handle({error, Reason}) ->
io:format("Error: ~p~n", [Reason]).
四、元组模式 #
4.1 固定大小元组 #
erlang
-module(tuple_match).
-export([demo/0]).
demo() ->
{A, B, C} = {1, 2, 3},
io:format("A=~p, B=~p, C=~p~n", [A, B, C]),
{point, X, Y} = {point, 10, 20},
io:format("X=~p, Y=~p~n", [X, Y]),
ok.
4.2 嵌套元组 #
erlang
-module(nested_tuple_match).
-export([demo/0]).
demo() ->
{A, {B, C}} = {1, {2, 3}},
io:format("A=~p, B=~p, C=~p~n", [A, B, C]),
{person, Name, {address, City}} =
{person, "Alice", {address, "Beijing"}},
io:format("Name=~p, City=~p~n", [Name, City]),
ok.
4.3 忽略部分 #
erlang
-module(ignore_match).
-export([demo/0]).
demo() ->
{_, B, _} = {1, 2, 3},
io:format("B = ~p~n", [B]),
{First, _, Third} = {a, b, c},
io:format("First=~p, Third=~p~n", [First, Third]),
ok.
五、列表模式 #
5.1 头尾模式 #
erlang
-module(list_head_tail).
-export([demo/0]).
demo() ->
[H | T] = [1, 2, 3, 4, 5],
io:format("Head=~p, Tail=~p~n", [H, T]),
ok.
5.2 多元素模式 #
erlang
-module(list_multi).
-export([demo/0]).
demo() ->
[A, B, C | Rest] = [1, 2, 3, 4, 5],
io:format("A=~p, B=~p, C=~p, Rest=~p~n", [A, B, C, Rest]),
[First, Second] = [a, b],
io:format("First=~p, Second=~p~n", [First, Second]),
ok.
5.3 空列表模式 #
erlang
-module(empty_list_match).
-export([process/1]).
process([]) -> empty;
process([H | T]) -> {non_empty, H, T}.
5.4 特定元素匹配 #
erlang
-module(specific_match).
-export([demo/0]).
demo() ->
[1, 2, 3] = [1, 2, 3],
[a, B, c] = [a, b, c],
io:format("B = ~p~n", [B]),
ok.
六、二进制模式 #
6.1 基本二进制匹配 #
erlang
-module(binary_match).
-export([demo/0]).
demo() ->
<<A, B, C>> = <<1, 2, 3>>,
io:format("A=~p, B=~p, C=~p~n", [A, B, C]),
ok.
6.2 固定位宽匹配 #
erlang
-module(bit_match).
-export([demo/0]).
demo() ->
<<Int:16>> = <<1, 2>>,
io:format("16-bit int: ~p~n", [Int]),
<<X:4, Y:4>> = <<16#AB:8>>,
io:format("X=~p, Y=~p~n", [X, Y]),
ok.
6.3 变长匹配 #
erlang
-module(varlen_binary_match).
-export([demo/0]).
demo() ->
<<Head:8, Rest/binary>> = <<1, 2, 3, 4, 5>>,
io:format("Head=~p, Rest=~p~n", [Head, Rest]),
ok.
七、映射模式 #
7.1 键值匹配 #
erlang
-module(map_match).
-export([demo/0]).
demo() ->
#{a := A, b := B} = #{a => 1, b => 2, c => 3},
io:format("A=~p, B=~p~n", [A, B]),
ok.
7.2 函数参数匹配 #
erlang
-module(map_func_match).
-export([process/1]).
process(#{name := Name, age := Age}) ->
io:format("Name: ~s, Age: ~p~n", [Name, Age]);
process(#{name := Name}) ->
io:format("Name: ~s (age unknown)~n", [Name]);
process(_) ->
io:format("Unknown~n").
八、守卫 #
8.1 基本守卫 #
erlang
-module(guard_basic).
-export([classify/1]).
classify(N) when N > 0 -> positive;
classify(N) when N < 0 -> negative;
classify(0) -> zero.
8.2 守卫序列 #
erlang
-module(guard_seq).
-export([demo/1]).
demo(N) when N > 0, N < 10 -> small;
demo(N) when N >= 10, N < 100 -> medium;
demo(N) when N >= 100 -> large.
8.3 守卫中的函数 #
erlang
-module(guard_func).
-export([process/1]).
process(X) when is_integer(X) -> integer;
process(X) when is_float(X) -> float;
process(X) when is_list(X) -> list;
process(X) when is_tuple(X) -> tuple;
process(_) -> other.
8.4 守卫限制 #
守卫中只能使用特定函数:
erlang
-module(guard_limit).
-export([valid/1, invalid/1]).
valid(X) when is_integer(X), X > 0 -> ok.
invalid(X) when my_func(X) -> ok.
允许的函数:
- 类型检测:
is_atom/1,is_integer/1,is_list/1等 - 比较:
=:=,=/=,<,>,=<,>= - 算术:
+,-,*,div,rem - 位运算:
band,bor,bnot,bsl,bsr - 其他:
abs/1,length/1,hd/1,tl/1,element/2
九、模式匹配应用 #
9.1 函数子句 #
erlang
-module(func_clause).
-export([factorial/1, fib/1]).
factorial(0) -> 1;
factorial(N) when N > 0 -> N * factorial(N - 1).
fib(0) -> 0;
fib(1) -> 1;
fib(N) when N > 1 -> fib(N - 1) + fib(N - 2).
9.2 case表达式 #
erlang
-module(case_expr).
-export([classify/1]).
classify(Value) ->
case Value of
{ok, Result} -> {success, Result};
{error, Reason} -> {failure, Reason};
_ -> unknown
end.
9.3 receive匹配 #
erlang
-module(receive_match).
-export([loop/0]).
loop() ->
receive
{ping, From} ->
From ! pong,
loop();
{stop, Reason} ->
io:format("Stopping: ~p~n", [Reason]),
stopped;
Other ->
io:format("Unknown message: ~p~n", [Other]),
loop()
end.
9.4 消息处理 #
erlang
-module(message_handling).
-export([handle/1]).
handle({request, Id, Data}) ->
io:format("Request ~p: ~p~n", [Id, Data]),
{response, Id, processed};
handle({response, Id, Result}) ->
io:format("Response ~p: ~p~n", [Id, Result]),
ok;
handle({error, Reason}) ->
io:format("Error: ~p~n", [Reason]),
error.
十、模式匹配技巧 #
10.1 使用_忽略 #
erlang
-module(ignore_pattern).
-export([first/1, second/1]).
first([H | _]) -> H.
second([_, H | _]) -> H.
10.2 使用带名忽略 #
erlang
-module(named_ignore).
-export([process/1]).
process({tag, _Value = Value}) ->
io:format("Value: ~p~n", [Value]),
Value.
10.3 模式匹配顺序 #
erlang
-module(match_order).
-export([process/1]).
process({specific, Value}) ->
{specific, Value};
process({specific, _, _}) ->
specific_tuple;
process({specific, _, _, _}) ->
specific_triple;
process({specific, _}) ->
specific_single;
process(_) ->
other.
十一、总结 #
本章学习了:
- 模式匹配的概念
- 匹配操作符
- 原子、元组、列表、二进制、映射模式
- 守卫表达式
- 模式匹配应用
- 模式匹配技巧
准备好学习复杂模式匹配了吗?让我们进入下一章。
最后更新:2026-03-27