pop方法会抛出异常吗?

3

pop函数的文档说明如下:

user> (doc pop)
-------------------------
clojure.core/pop
([coll])
  For a list or queue, returns a new list/queue without the first
  item, for a vector, returns a new vector without the last item. If
  the collection is empty, throws an exception.

然而,我无法重现应该抛出异常的行为。

例如,在此处,我将三个元素添加到队列中,然后pop五次:根据文档,这不应该起作用。 但是,我没有遇到异常,而是得到了nil。

(peek (pop (pop (pop (pop (pop (conj (conj (conj clojure.lang.PersistentQueue/EMPTY 4) 5) 6)))))))

现在我很喜欢当尝试从空队列pop时,返回一个空队列而不是抛出异常的行为,但我想知道为什么这种行为与文档不同(至少从我阅读文档的理解来看)。
基本上,我想知道是否应该在此处“保护”自己免受异常影响,或者我是否可以安全地假定pop一个空队列将始终返回一个空队列(这与文档相矛盾)。
1个回答

1
你是正确的,文档字符串中似乎存在矛盾。目前,弹出一个空队列会得到一个空队列。从PersistentQueue的源代码的评论来看,核心开发人员似乎在讨论所需的行为。
public PersistentQueue pop(){
    if(f == null) //hmmm... pop of empty queue -> empty queue?
        return this;
    //throw new IllegalStateException("popping empty queue");
    ISeq f1 = f.next();
    PersistentVector r1 = r;
    if(f1 == null)
        {
        f1 = RT.seq(r);
        r1 = null;
        }
    return new PersistentQueue(meta(), cnt - 1, f1, r1);
}

我不认为自己是安全的,假设这种行为将来永远不会改变。


如果我想采取防御措施,我能否编写一个safe-pop函数,在底层使用try / catch并在抛出异常时返回nil? - Cedric Martin
我不知道如何捕获一个尚不存在(也许永远不会存在)的异常。我可能更倾向于自己测试是否为空,然后根据需要抛出异常或返回nil。 - A. Webb

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接