Erlang函数基础 #
一、函数概述 #
函数是Erlang程序的基本构建块,每个函数都属于一个模块。
1.1 函数特点 #
- 函数必须定义在模块中
- 函数名是原子
- 支持多子句
- 支持模式匹配参数
- 支持守卫条件
二、函数定义 #
2.1 基本语法 #
erlang
-module(basic_function).
-export([add/2, greet/1]).
add(A, B) -> A + B.
greet(Name) -> io:format("Hello, ~s!~n", [Name]).
2.2 函数导出 #
erlang
-module(export_demo).
-export([public_func/1]).
-export([another_public/2]).
public_func(X) -> X.
another_public(A, B) -> {A, B}.
private_func(X) -> X * 2.
2.3 export_all #
erlang
-module(export_all_demo).
-compile(export_all).
func1() -> ok.
func2() -> ok.
注意:仅用于开发调试,生产环境不建议使用。
三、多子句函数 #
3.1 基本多子句 #
erlang
-module(multi_clause).
-export([classify/1]).
classify(0) -> zero;
classify(N) when N > 0 -> positive;
classify(N) when N < 0 -> negative.
3.2 模式匹配子句 #
erlang
-module(pattern_clause).
-export([process/1]).
process([]) -> empty;
process([H]) -> {one, H};
process([H1, H2]) -> {two, H1, H2};
process([H | T]) -> {many, H, T}.
3.3 子句顺序 #
erlang
-module(clause_order).
-export([process/1]).
process({specific, Value}) -> {specific, Value};
process({specific, _, _}) -> specific_tuple;
process({specific, _}) -> specific_single;
process(_) -> other.
注意:更具体的模式应该放在前面。
3.4 默认子句 #
erlang
-module(default_clause).
-export([handle/1]).
handle({ok, Value}) -> {success, Value};
handle({error, Reason}) -> {failure, Reason};
handle(_) -> unknown.
四、函数参数 #
4.1 位置参数 #
erlang
-module(positional_args).
-export([create_user/3]).
create_user(Name, Age, Email) ->
#{name => Name, age => Age, email => Email}.
4.2 模式匹配参数 #
erlang
-module(pattern_args).
-export([extract/1]).
extract({point, X, Y}) -> {x, X, y, Y};
extract({person, Name, Age}) -> {name, Name, age, Age};
extract(Other) -> {unknown, Other}.
4.3 嵌套模式参数 #
erlang
-module(nested_pattern_args).
-export([process/1]).
process({request, {header, Id}, {body, Data}}) ->
#{id => Id, data => Data}.
4.4 忽略参数 #
erlang
-module(ignore_args).
-export([first/1, second/1]).
first([H | _]) -> H.
second([_, H | _]) -> H.
五、守卫 #
5.1 基本守卫 #
erlang
-module(basic_guard).
-export([abs/1, max/2]).
abs(N) when N < 0 -> -N;
abs(N) -> N.
max(A, B) when A > B -> A;
max(_, B) -> B.
5.2 多条件守卫 #
erlang
-module(multi_guard).
-export([classify_age/1]).
classify_age(Age) when Age < 13 -> child;
classify_age(Age) when Age >= 13, Age < 20 -> teenager;
classify_age(Age) when Age >= 20, Age < 65 -> adult;
classify_age(Age) when Age >= 65 -> senior.
5.3 守卫序列 #
erlang
-module(guard_sequence).
-export([validate/1]).
validate(X) when is_integer(X), X > 0, X < 100 -> valid;
validate(X) when is_float(X) -> valid_float;
validate(_) -> invalid.
5.4 守卫函数 #
erlang
-module(guard_functions).
-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(X) when is_binary(X) -> binary;
process(X) when is_atom(X) -> atom;
process(_) -> other.
六、函数调用 #
6.1 本地调用 #
erlang
-module(local_call).
-export([outer/1]).
outer(X) ->
Inner = inner(X),
{outer, Inner}.
inner(X) -> {inner, X}.
6.2 模块调用 #
erlang
-module(module_call).
-export([demo/0]).
demo() ->
Result = lists:map(fun(X) -> X * 2 end, [1, 2, 3]),
io:format("Result: ~p~n", [Result]).
6.3 完全限定调用 #
erlang
-module(fully_qualified).
-export([demo/0]).
demo() ->
Result = my_module:my_function(42),
{result, Result}.
my_function(X) -> X * 2.
6.4 动态模块调用 #
erlang
-module(dynamic_call).
-export([call/3]).
call(Module, Function, Args) ->
apply(Module, Function, Args).
七、函数返回值 #
7.1 单一返回值 #
erlang
-module(single_return).
-export([double/1]).
double(X) -> X * 2.
7.2 元组返回值 #
erlang
-module(tuple_return).
-export([divide/2]).
divide(_, 0) -> {error, division_by_zero};
divide(A, B) -> {ok, A / B}.
7.3 多返回值处理 #
erlang
-module(multi_return).
-export([process/1]).
process(Data) ->
case divide(Data, 2) of
{ok, Result} -> {success, Result};
{error, Reason} -> {failure, Reason}
end.
divide(_, 0) -> {error, division_by_zero};
divide(A, B) -> {ok, A / B}.
八、函数文档 #
8.1 Edoc格式 #
erlang
-module(edoc_example).
-export([add/2, factorial/1]).
add(A, B) -> A + B.
factorial(0) -> 1;
factorial(N) when N > 0 -> N * factorial(N - 1).
8.2 模块文档 #
erlang
-module(module_doc).
-export([process/1]).
process(Data) -> Data.
九、函数规范 #
9.1 类型规范 #
erlang
-module(type_spec).
-export([add/2, greet/1]).
-spec add(number(), number()) -> number().
add(A, B) -> A + B.
-spec greet(string()) -> ok.
greet(Name) -> io:format("Hello, ~s!~n", [Name]).
9.2 复杂类型规范 #
erlang
-module(complex_spec).
-export([process/1]).
-type result() :: {ok, term()} | {error, term()}.
-type input() :: integer() | float() | string().
-spec process(input()) -> result().
process(X) when is_number(X) -> {ok, X * 2};
process(X) when is_list(X) -> {ok, string:uppercase(X)};
process(_) -> {error, invalid_input}.
十、函数最佳实践 #
10.1 函数命名 #
erlang
-module(naming_practice).
-export([get_user_name/1, calculate_total_price/2, is_valid_email/1]).
get_user_name(User) -> maps:get(name, User).
calculate_total_price(Price, Quantity) -> Price * Quantity.
is_valid_email(Email) -> string:find(Email, "@") =/= nomatch.
命名规范:
- 使用小写字母和下划线
- 动词开头表示动作
- 布尔函数以
is_开头 - 名称要有意义
10.2 函数长度 #
erlang
-module(function_length).
-export([good/1, bad/1]).
good(Data) ->
Validated = validate(Data),
Transformed = transform(Validated),
save(Transformed).
bad(Data) ->
validate(Data),
transform(Data),
save(Data).
validate(D) -> D.
transform(D) -> D.
save(D) -> D.
10.3 单一职责 #
erlang
-module(single_responsibility).
-export([process_user/1]).
process_user(Data) ->
User = create_user(Data),
validate_user(User),
save_user(User),
{ok, User}.
create_user(Data) -> Data.
validate_user(_User) -> ok.
save_user(_User) -> ok.
10.4 避免深层嵌套 #
erlang
-module(avoid_nesting).
-export([good/1, bad/1]).
bad(Data) ->
case step1(Data) of
{ok, R1} ->
case step2(R1) of
{ok, R2} ->
case step3(R2) of
{ok, R3} -> {ok, R3};
{error, E} -> {error, E}
end;
{error, E} -> {error, E}
end;
{error, E} -> {error, E}
end.
good(Data) ->
with(Data, [
fun step1/1,
fun step2/1,
fun step3/1
]).
with({error, _} = Error, _) -> Error;
with({ok, Value}, [Fun | Rest]) -> with(Fun({ok, Value}), Rest);
with({ok, Value}, []) -> {ok, Value}.
step1(D) -> {ok, D}.
step2(D) -> {ok, D}.
step3(D) -> {ok, D}.
十一、总结 #
本章学习了:
- 函数定义语法
- 多子句函数
- 函数参数
- 守卫表达式
- 函数调用方式
- 函数返回值
- 函数文档和规范
- 最佳实践
准备好学习递归函数了吗?让我们进入下一章。
最后更新:2026-03-27