Erlang Thursday – queue:tail/1

今天的Erlang Thursday我们继续queue模块的Okazaki API,来讲讲 queue:tail/1.

queue:tail/1 接收一个非空队列入参,返回移除了第一个元素的新队列。

1
2
3
4
5
6
7
8
9
10
Queue = queue:from_list([1, 2, 3, 4, 5]).
% {[5,4],[1,2,3]}
Tail = queue:tail(Queue).
% {[5,4],[2,3]}
Queue.
% {[5,4],[1,2,3]}
queue:head(Tail).
% 2
queue:to_list(Tail).
% [2,3,4,5]

我们可以看到上述调用 queue:tail/1 的例子不像其它语言一样是一个破坏性操作,它完全保留了原始的入参队列的完整性。

做为将一个队列做为双端来处理的Okasaki API的一部分,queue:tail/1 有一个对应的函数 queue:liat/1 ,这个函数返回移除入参队列的最后一个元素后形成的新队列。queue:liat/1 也有一个别名函数,就是Okasaki API的 queue:init/1.

1
2
3
4
5
6
queue:liat(Queue).
% {[4],[1,2,3]}
queue:init(Queue).
% {[4],[1,2,3]}
Queue.
% {[5,4],[1,2,3]}

注意:Erlang官方文档也指出有一个别名函数 queue:lait/1 ,大家最好不要用它,因为它的拼写是错误的。

因为我们是要深入细节然后看看我们能学到什么,那么让我们一起来到目前为止我们接触到的不同的tail函数在接收一个空队列为入参会发生什么。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
EmptyQueue = queue:new().
% {[],[]}
queue:tail(EmptyQueue).
% ** exception error: empty
% in function queue:drop/1
% called as queue:drop({[],[]})
queue:liat(EmptyQueue).
% ** exception error: empty
% in function queue:drop_r/1
% called as queue:drop_r({[],[]})
queue:init(EmptyQueue).
% ** exception error: empty
% in function queue:drop_r/1
% called as queue:drop_r({[],[]})

当我们分别调用 queue:tail/1queue:liat/1 的时候,看起来像我们在调用 queue:drop/1 和 queue:drop_r/1 得到的异常错误一样。

当我们用一个有若干元素的队列做为入参来调用 queue:drop/1 和 queue:drop_r/1 ,然后看看的执行情况,看起来 queue:tail/1 就是 queue:drop/1 的别名函数,而 queue:list/1 和 queue:init/1 就是 queue:drop_r/1 的别名函数。

1
2
3
4
queue:drop(Queue).
% {[5,4],[2,3]}
queue:drop_r(Queue).
{[4],[1,2,3]}

原文链接: https://www.proctor-it.com/erlang-thursday-queue-tail-1/