You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何在fiveam测试环境中调用`member`函数表现异常?

问题原因分析

你遇到的差异本质是字符串字面量的对象同一性问题,结合Common Lisp的eql判定规则和FiveAM的编译优化导致:

核心规则

eql对字符串的判定逻辑是:只有当两个字符串是内存中的同一个对象时才返回真,而非比较字符串内容。如果需要判断字符串内容是否匹配,应该用equal或string=。

两种环境的差异

  1. 普通Common Lisp解释器会话:
    解释器通常不会对字符串字面量做池化优化,代码里的两个"foo"是独立的内存对象(地址不同)。因此(eql "foo" "foo")返回NIL,member找不到匹配项,最终返回NIL。

  2. FiveAM测试环境:
    FiveAM运行测试时会编译执行代码,且默认启用了字符串字面量共享优化——编译时会把相同内容的字符串字面量合并为同一个内存对象。此时测试代码里的两个"foo"是同一个对象,(eql "foo" "foo")返回T,member找到匹配项,返回("foo")。

验证与解决

  • 验证:在两种环境下分别执行(eq "foo" "foo"),普通环境返回NIL,FiveAM环境返回T(eq是eql的子集,对字符串判定逻辑一致)。
  • 解决:如果需求是判断字符串内容是否存在,将测试函数换成#'equal或#'string=即可:
    (member "foo" '("foo") :test #'equal)
    

复现代码

test.lisp

#!/usr/bin/env -S sbcl --script

(load "~/.quicklisp/setup")
(require :asdf)

(ql:quickload "fiveam" :silent t)
(load "mre.asd")
(asdf:load-system :mre)

(asdf:test-system :mre)
(format t "~&(member \"foo\" '(\"foo\") :test #'eql) evaluates to: ~A~%"
        (member "foo" '("foo") :test #'eql))

mre.asd

(asdf:defsystem "mre"
  :depends-on ("fiveam")
  :components ((:file "mre"))
  :perform (asdf:test-op
            (o c)
            (uiop:symbol-call :fiveam :run!
                              (find-symbol* '#:mre-tests :mre))))

mre.lisp

(defpackage :mre
  (:use :cl :fiveam)
  (:export :utils-sets-hasduplicatesp))

(in-package :mre)

(def-suite mre-tests)
(in-suite mre-tests)

(test member-test
      (is-false (member "foo" '("foo") :test #'eql)))

运行结果

$ ./test.lisp 
./test.lisp 

Running test suite MRE-TESTS
 Running test MEMBER-TEST f
 Did 1 check.
    Pass: 0 ( 0%)
    Skip: 0 ( 0%)
    Fail: 1 (100%)

 Failure Details:
 --------------------------------
 MEMBER-TEST in MRE-TESTS []: 
      (MEMBER "foo" '("foo") :TEST #'EQL) returned the value ("foo"), which is true
 --------------------------------

(member "foo" '("foo") :test #'eql) evaluates to: NIL 

内容的提问来源于stack exchange,提问作者vmonteco

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.11 18:42:20