ch05-记录与映射组
-
记录:可以给元组里的各个元素关联一个名称
-
映射组:哈希表
-
rr(read records)
-
映射组
- K => V 更新或者新增
- K := V 更新,新增会报错
练习答案
(1)
需要用到第三方库
parse_file(File) ->
case file:read_file(File) of
{ok, Content} -> case rfc4627:decode(Content) of
{ok, Result, _} -> Result;
{error, Reason} -> io:format("rfc4627:decode error:~p~n", [Reason])
end;
{error, Reason} -> io:format("file:read_file error:~p~n", [Reason])
end.
(2)
map_search_pred(Map, Pred) ->
map_search_pred(Map, maps:keys(Map), Pred).
map_search_pred(Map, [Key|T], Pred) ->
case Pred(Key, maps:get(Key, Map)) of
true -> {Key, maps:get(Key, Map)};
false -> map_search_pred(Map, T, Pred)
end;
map_search_pred(_, [], _) ->
io:format("not found~n").
pred(Key, Value) ->
case (Key =:= Value) of
true -> true;
false -> false
end.
测试:
19> answers:map_search_pred(#{ a => 1, b => 2, c => c}, fun(Key, Value) -> answers:pred(Key, Value) end).
ch06-顺序程序的错误处理
练习答案
(1)
-module(myfile).
-export([read/1]).
read(File) ->
try file:read_file(File) of
{ok, Content} -> Content;
{error, Reason} -> Reason
catch
throw:X -> io:format("throw Reason is:~p~n", [X]);
end.
(2)
catcher(N) ->
try generate_exception(N) of
Val -> {N, normal, Val}
catch
throw:X:Stacktrace ->
{user, N, caught, throw, X},
{developer, X, Stacktrace};
exit:X:Stacktrace ->
{N, caught, exited, X},
{developer, X, Stacktrace};
error:X:Stacktrace ->
{N, caught, error, X},
{developer, X, Stacktrace}
end.
ch07-二进制型与位语法
-
binary -> 位数是8的倍数
-
bitstring -> 位数不是8的倍数
-
<<<“hello”>>
课后答案
(1)
reverse_bytes(Bin) ->
reverse_bytes(Bin, <<>>, 1).
reverse_bytes(Bin, BinRet, Pos) when Pos =< byte_size(Bin) ->
{Bin1, Bin2} = split_binary(Bin, 1),
reverse_bytes(Bin2, list_to_binary([Bin1, BinRet]), Pos);
reverse_bytes(Bin, BinRet, Pos) when Pos > byte_size(Bin) ->
BinRet.
(2)
term_to_packet(Term) ->
Bin = term_to_binary(Term),
Length = bit_size(Bin),
Size = <<Length:1/unit:32>>,
<<Size/binary, Bin/binary>>.
(3)
packet_to_term(Packet) ->
<<Head:32/bits,_/bits>> = Packet,
<<Size:32>> = Head,
Length=Size*8,%取bit长度
<<Head:32/bits,Data:Length/bits>>=Packet,
binary_to_term(Data).
(5)
reverseBits(Bits)->
lists:reverse([ X || <<X:1>> <= Bits ]).
ch08-顺序编程补遗
课后答案
(2)
-module(answers).
-export([get_max_func_mod/0, get_most_common_func/0, get_once_func/0]).
list_size(L) ->
list_size(L, 0).
list_size([_|T], Size) ->
list_size(T, Size+1);
list_size([], Size) ->
Size.
%% 最多导出函数的模块
get_max_func_mod() ->
get_max_func_mod("", code:all_loaded(), -1).
get_max_func_mod(_, [H|T], Max) ->
{Name, _} = H,
[_, {exports, L}, _, _, _] = Name:module_info(),
case (list_size(L) > Max) of
true -> get_max_func_mod(Name, T, list_size(L));
false -> get_max_func_mod(Name, T, Max)
end;
get_max_func_mod(Mod, [], Max) ->
{Mod, Max}.
%% 最常见的函数名
get_most_common_func() ->
get_most_common_func(code:all_loaded(), #{}).
get_most_common_func([H|T], Map) ->
{Name, _} = H,
[_, {exports, L}, _, _, _] = Name:module_info(),
get_most_common_func(T, count_func(L, Map));
get_most_common_func([], Map) ->
find_max(Map).
count_func([H|L], Map) ->
{Func, _} = H,
case maps:is_key(Func, Map) of
true -> count_func(L, Map#{Func => maps:get(Func, Map)+1});
false -> count_func(L, Map#{Func => 1})
end;
count_func([], Map) ->
Map.
find_max(X) ->
L = maps:keys(X),
find_max(L, X, "", -1).
find_max([H|T], X, MaxKey, MaxValue) ->
{ok, Value} = maps:find(H, X),
case (Value > MaxValue) of
true -> find_max(T, X, H, Value);
false -> find_max(T, X, MaxKey, MaxValue)
end;
find_max([], _, MaxKey, MaxValue) ->
{MaxKey, MaxValue}.
%% 只出现过一次的函数
get_once_func() ->
get_once_func(code:all_loaded(), #{}).
get_once_func([H|T], Map) ->
{Name, _} = H,
[_, {exports, L}, _, _, _] = Name:module_info(),
get_once_func(T, count_func(L, Map));
get_once_func([], Map) ->
find_one(Map).
find_one(Map) ->
Keys = maps:keys(Map),
lists:filter(fun(K) -> {ok, Value} = maps:find(K, Map), Value =:= 1 end, Keys).