书承上篇,写道了http_server模块中的httpd_sup.erl中start_link函数和它的回调函数init;代码如下:
%%%========================================================================= %%% API %%%========================================================================= start_link(HttpdServices) -> supervisor:start_link({local, ?MODULE}, ?MODULE, [HttpdServices]). start_link(HttpdServices, stand_alone) -> supervisor:start_link(?MODULE, [HttpdServices]). .......... %%%========================================================================= %%% Supervisor callback %%%========================================================================= init([HttpdServices]) -> RestartStrategy = one_for_one, MaxR = 10, MaxT = 3600, Children = child_specs(HttpdServices, []), {ok, {{RestartStrategy, MaxR, MaxT}, Children}}.
有个疑问,为什么这里HttpdServices本来就是一个List,为什么init函数定义时要使用方括号把HttpdServices包起来呢?
做个实验,测试代码如下:
1 -module(test_list). 2 3 -export([init/1, init/6, func/2]). 4 5 6 init([Li]) -> 7 io:format("List maybe as : ~p~n", [Li]). 8 9 init(L1, L2, L3, L4, L5, L6) -> 10 io:format("fucker, item in List is : ~w~n", [L1]), 11 io:format("fucker, item in List is : ~w~n", [L2]), 12 io:format("fucker, item in List is : ~w~n", [L3]), 13 io:format("fucker, item in List is : ~w~n", [L4]), 14 io:format("fucker, item in List is : ~w~n", [L5]), 15 io:format("fucker, item in List is : ~w~n", [L6]). 16 17 func(Li, Tp) -> 18 io:format("List maybe as : ~p~n", [Li]), 19 io:format("Tuple maybe as : ~p~n", [Tp]). 20
实验过程,记录如下:
31> L1. [1,2,3,555,6,7,8] 32> L2. [1,3,44,56,7,666]
34> T1 = {1,11}.
{1,11}
35> T2 = {2,22}.
{2,22}
36> T3 = {3,33}.
{3,33}
37> T4 = {4,44}.
{4,44}
38> T5 = {5,55}.
{5,55}
39> T6 = {6,66}.
{6,66}
40> L3 = [T1, T2, T3, T4, T5, T6].
43> L3. [{1,11},{2,22},{3,33},{4,44},{5,55},{6,66}] 44>
48> test_list:init(L2).
** exception error: no function clause matching
test_list:init([1,3,44,56,7,666]) (test_list.erl, line 6)
49>
54> test_list:init(L3). ** exception error: no function clause matching test_list:init([{1,11}, {2,22}, {3,33}, {4,44}, {5,55}, {6,66}]) (test_list.erl, line 6)
59> test_list:init(T1, T2, T3, T4, T5, T6).
fucker, item in List is : {1,11}
fucker, item in List is : {2,22}
fucker, item in List is : {3,33}
fucker, item in List is : {4,44}
fucker, item in List is : {5,55}
fucker, item in List is : {6,66}
ok
60> test_list:init(1,2,3,45,6,7).
fucker, item in List is : 1
fucker, item in List is : 2
fucker, item in List is : 3
fucker, item in List is : 45
fucker, item in List is : 6
fucker, item in List is : 7
ok
61>
61> test_list:init(L1,2,3,45,6,7).
fucker, item in List is : [1,2,3,555,6,7,8]
fucker, item in List is : 2
fucker, item in List is : 3
fucker, item in List is : 45
fucker, item in List is : 6
fucker, item in List is : 7
ok
62> test_list:init(L1,T2,3,45,6,7).
fucker, item in List is : [1,2,3,555,6,7,8]
fucker, item in List is : {2, 22}
fucker, item in List is : 3
fucker, item in List is : 45
fucker, item in List is : 6
fucker, item in List is : 7
ok
63>
对于init/6函数,L2和L3都有6个元素,似乎跟init/6能匹配,但是结果很明显:不能!
List和其他元素,组成的6个,可以匹配init/6;
List、Tuple和其他元素,组成的6个,也可以匹配init/6;
但是唯独6个元素的List,不能匹配init/6。
64> test_list:init(L1). ** exception error: no function clause matching test_list:init([1,2,3,555,6,7,8]) (test_list.erl, line 6) 65> test_list:init(L2). ** exception error: no function clause matching test_list:init([1,3,44,56,7,666]) (test_list.erl, line 6) 66> test_list:init([L1,L2]). ** exception error: no function clause matching test_list:init([[1,2,3,555,6,7,8],[1,3,44,56,7,666]]) (test_list.erl, line 6) 67> test_list:init([[L1,L2]]). List maybe as : [[1,2,3,555,6,7,8],[1,3,44,56,7,666]] ok 68>
69> test_list:init([L2]).
List maybe as : [1,3,44,56,7,666]
ok
72> test_list:init([L3]).
List maybe as : [{1,11},{2,22},{3,33},{4,44},{5,55},{6,66}]
ok
对于init/1函数,L1和L2作为一个List,似乎跟init/1能匹配,但是结果很明显:还是不能!
[L1, L2]算是一个List结构,也不能匹配!
只有[L1], [L2], [[L1, L2]],都可以匹配!
所以似乎可以得到这个结论:当只有一个List结构作为参数时,必须使用方括号包起来;
init([HttpdServices])这样使用方括号把List结构包住,才能处理HttpdServices作为一个长度不定的List的情况。