use erlang

启动

erl

说明

.结尾一个语句

-module(geometry). %模块声明,模块名必须与文件名相同。
-export([area/1]). %导出声明,声明可以外部使用的函数
area({rectangle, Width, Height}) -> Width*Height; %子句1
area({square, Side}) -> Side * Side.%子句2

在erl中用c(“文件名.erl”). 去编译

定义一个函数

Double = fun(X)->2*X end. %变量名是必须大写的
Double(2).

使用模块:函数

L=[1,2,3,4].
lists:map(Double,L).

使用=:=来判断相等

lists:filter(fun(X)->(X rem 2)=:=0 end,[1,2,3,4,5,6]). %函数可拿来当作其他函数的参数

高阶函数(返回函数的函数)

Fruit = [pear,apple,orange].
MakeTest = fun(L)->(fun(X)->lists:mamber(X,L) end) end.
isFruit=MakeTest(Fruit).
isFruit(apple).

Type System

– 原子类型

  1. 以小写开头,原子类型与变量不同,变量有值,原子类型没有
  2. 原子是一种描述,一种字面常量,它本身就是最小了
  3. ‘…’ 引导的串是原子
    – 元组
  4. {atom_what_ever,T_OF_VARIABLE}
    – 列表可以加入其他任意类型
    [{…},{a,{…}} | {…}]
    – 没有字符串,但用数字列表来表示字符串
  5. [97,98,99] => “abc”
  6. unicode
    – 映射map
  7. #{“key”=>32}
    – 二进制串
  8. <<1,2,3,…>>
    – 进制值表示
  9. 2#10101111000
  10. 16#ffff

io例子

io:format("~w ~w~n",[hello,world]).%格式化输出,类似于printf

模式匹配和case等价性

一些例子

  1. tut
  2. temp_convert
  3. color
  4. if_case
  5. case_test
  6. spawn_test
  7. process_in_erlang
  8. reg_a_pro
  9. proc_dict
  10. fnc
  11. err_handle

进程

%变量不可重赋值,这里只有绑定变量概念
%函数名必须是原子
%模块声明,模块名必须与文件名相同。
-module(tut).
%导出声明,声明可以外部使用的函数
-export([area/1, test/0]).
% area函数的定义
%子句1
area({rectangle, Width, Height}) -> Width * Height;
%子句2
area({square, Side}) -> Side * Side.
% area函数定义结束
test() ->
    12 = area({rectangle, 3, 4}),
    %如果左右不相等,会调用报错
    169 = area({square, 13}),
    %使用:tut:test().
    tests_worked.
%模块声明,模块名必须与文件名相同。
-module(tut).
%导出声明,声明可以外部使用的函数
-export([area/1, test/0]).
% area函数的定义
%子句1
area({rectangle, Width, Height}) -> Width * Height;
%子句2
area({square, Side}) -> Side * Side.
% area函数定义结束
test() ->
    12 = area({rectangle, 3, 4}),
    %如果左右不相等,会调用报错
    169 = area({square, 13}),
    %使用:tut:test().
    tests_worked.
-module(color).
-export([new/4, blend/2, test/0]).
%宏定义,宏用的作用主要是方便检查V
-define(is_channel(V), (is_float(V) andalso V >= 0.0 andalso V =< 1.0)).
new(R, G, B, A) when ?is_channel(R), ?is_channel(G), ?is_channel(B), ?is_channel(A) ->
    #{red => R, green => G, blue => B, alpha => A}.

blend(Src, Dst) ->
    blend(Src, Dst, alpha(Src, Dst)).
blend(Src, Dst, Alpha) when Alpha > 0.0 ->
    Dst#{
        % 更新已存在的映射键值对可以用 := 操作符
        red := red(Src, Dst) / Alpha,
        green := green(Src, Dst) / Alpha,
        blue := blue(Src, Dst) / Alpha,
        alpha := Alpha
    };
blend(_, Dst, _) ->
    Dst#{
        red := 0.0,
        green := 0.0,
        blue := 0.0,
        alpha := 0.0
    }.
alpha(#{alpha := SA}, #{alpha := DA}) ->
    SA + DA * (1.0 - SA).
red(#{red := SV, alpha := SA}, #{red := DV, alpha := DA}) ->
    SV * SA + DV * DA * (1.0 - SA).

green(#{green := SV, alpha := SA}, #{green := DV, alpha := DA}) ->
    SV * SA + DV * DA * (1.0 - SA).
blue(#{blue := SV, alpha := SA}, #{blue := DV, alpha := DA}) ->
    SV * SA + DV * DA * (1.0 - SA).
test() ->
    C1 = color:new(0.3, 0.4, 0.5, 1.0),
    C2 = color:new(1.0, 0.8, 0.1, 0.3),
    color:blend(C1, C2),
    color:blend(C2, C1),
    %return the atomic value
    tests_worked.
% erl
% c(color).
% color:test().
-module(if_case).
-export([test_if/2]).

test_if(A, B) ->
    if
        A == 5 ->
            io:format("A == 5~n", []),
            %% this value will return
            a_equals_5;
        B == 6 ->
            io:format("B == 6~n", []),
            b_equals_6;
        %That is A equals 2 and B equals 3
        A == 2, B == 3 ->
            io:format("A == 2, B == 3~n", []),
            a_equals_2_b_equals_3;
        %That is A equals 1 or B equals 7
        A == 1; B == 7 ->
            io:format("A == 1 ; B == 7~n", []),
            a_equals_1_or_b_equals_7
    end.
-module(case_test).
-export([month_length/2, test/0]).

month_length(Year, Month) ->
    %% 被 400 整除的为闰年。
    %% 被 100 整除但不能被 400 整除的不是闰年。
    %% 被 4 整除但不能被 100 整除的为闰年。
    Leap =
        if
            trunc(Year / 400) * 400 == Year ->
                leap;
            trunc(Year / 100) * 100 == Year ->
                not_leap;
            trunc(Year / 4) * 4 == Year ->
                leap;
            true ->
                not_leap
        end,
    case Month of
        sep -> 30;
        apr -> 30;
        jun -> 30;
        nov -> 30;
        feb when Leap == leap -> 29;
        feb -> 28;
        jan -> 31;
        mar -> 31;
        may -> 31;
        jul -> 31;
        aug -> 31;
        oct -> 31;
        dec -> 31
    end.
test() ->
    io:format("~w~n", [month_length(2004, feb)]),
    io:format("~w~n", [month_length(1944, feb)]),
    io:format("~w~n", [month_length(1947, feb)]).
-module(spawn_test).
-export([start/0, say_something/2]).

say_something(_, 0) ->
    done;
say_something(What, Times) ->
    io:format("~p~n", [What]),
    say_something(What, Times - 1).

start() ->
    spawn(spawn_test, say_something, [hello, 3]),
    spawn(spawn_test, say_something, [goodbye, 3]).

-module(process_in_erlang).
-compile(export_all).
% erlang的发送消息机制就是底层c语言做的复制要发送信息到另一个进程
% 进程看作是数据类型,这个进程不像其他语言中的进/线程,不共享内存,不会有数据共享,也没有上锁机制
% 进程通信就是是相互发消息机制,根据pid,pid可以注册一个名字

% 例子s
run() ->
    A_Server = spawn(process_in_erlang, cosume_server, []),
    A_Server ! {self(), helloworld},
    receive
        {Pid, Msg} ->
            io:format("receive ~p from ~p~n", [Msg, Pid])
    end,
    %发一个stop
    A_Server ! {self(), stop},
    ok.
cosume_server() ->
    % 会阻塞以至于模式匹配
    receive
        {Pid, Msg} ->
            case Msg of
                % 当接受到的消息是stop
                stop ->
                    true;
                % 其他任意
                _ ->
                    io:format("~p~n", [Msg]),
                    % 发消息到Pid
                    Pid ! {self(), Msg},
                    %递归
                    cosume_server()
            end
    end.
-module(reg_a_pro).
-compile(export_all).

run() ->
    register(me, self()),
    register(lServer, spawn(reg_a_pro, loop, [])),
    sleep(5000),
    lServer ! {me, helloworld},
    receive
        {Pid, Msg} ->
            io:format("receive ~p from ~p~n", [Msg, Pid])
    end,
    lServer ! {me, stop},
    ok.

loop() ->
    receive
        {Pid, Msg} ->
            case Msg of
                stop ->
                    true;
                _ ->
                    io:format("~p~n", [Msg]),
                    me ! {self(), Msg},
                    loop()
            end
    after 1000 ->
        io:format("no msg~n"),
        loop()
    end.
sleep(Internal) ->
    receive
    after Internal ->
        ok
    end.
-module(proc_dict).
-compile(export_all).
% 进程字典,键值对,put(),get(),erase(),可在进程存放一些键值对
% 这些键值对只能在本进程可见可写
start(Version) ->
    put(xjb, 1),
    spawn(proc_dict, loop, [Version]),
    tt().

tt() ->
    io:format("pid ~p xjb is ~p~n", [self(), get(xjb)]).
sleep() ->
    receive
    after 2000 -> ok
    end.
loop(Version) ->
    sleep(),
    Val = what,
    io:format("version ~p value is ~p~n", [Version, Val]),
    loop(Version).
-module(fnc).
-author("etcix").
-compile(export_all).
a_funcname_must_be_atom() ->
    ok.
pat_mat_test(X, Y, Z) ->
    case X of
        add -> Y + Z;
        sub -> Y - Z;
        _ -> nothing
    end.
% 等价于
calc(add, X, Y) ->
    X + Y;
calc(sub, X, Y) ->
    X - Y;
calc(_, _, _) ->
    nothing.

% lambda
% map,filter

% 经典例子
cost(apple) -> 3;
cost(banana) -> 4;
cost(peach) -> 5.
shop([]) -> 0;
shop([{Name, Num} | T]) -> cost(Name) * Num + shop(T).

shop_v2(X) ->
    case X of
        [{Name, Num} | T] -> Num * cost(Name) + shop_v2(T);
        [] -> 0
    end.
test() ->
    shop_v2([{apple, 5}, {banana, 2}]).
test_lambda() ->
    lists:map(fun(X) -> X * 2 end, [1, 1, 2, 3, 4, 4, 1, 213, 42]),
    lists:filter(fun(X) -> X + 2 =:= 3 end, [1, 1, 1, 2, 3, 4, 4]).
-module(err_handle).
-author("etcix").
-compile(export_all).

% error
% exit
% throw
% of对于try结果匹配
test() ->
    try
        1 / 0
    catch
        % Type,Reson,Stack
        % _:R:Stack -> {err, R, Stack}
        error:Error -> {error, Error};
        exit:Exit -> {exit, Exit};
        throw:Throw -> {throw, Throw}
    end.
throw_test() ->
    try
        % 主动引发,写入任意错误字符串
        throw("fucking error")
    catch
        x:R -> {x, R}
    after
        % 等价于finally
        io:format("~p~n", ["final scope"])
    end.
of_test() ->
    try 1 - 1 of
        0 -> ok;
        10 -> no
    after
        io:format("~p~n", ["final scope"])
    end.

你可能感兴趣的:(zig学习,erlang)