比较列表时Clojure的deftest宏中出现断言错误

比较列表时Clojure的deftest宏中出现断言错误,clojure,clojure-testing,Clojure,Clojure Testing,我的问题是关于Clojures deftest宏,或者更一般地说是关于如何比较函数创建的列表。但我对Clojure还不熟悉,无法识别具体原因。也许还有其他人有想法 首先,报告的信息: 未能通过符号列表测试util_test.clj:105 预期:=将a not b c引用到符号列表[a not b c]实际:not=a not b c a not b c 但很明显,=a not b c a not b c quoted应该是真的 第二,具体测试代码: (deftest to-symbol-lis

我的问题是关于Clojures deftest宏,或者更一般地说是关于如何比较函数创建的列表。但我对Clojure还不熟悉,无法识别具体原因。也许还有其他人有想法

首先,报告的信息:

未能通过符号列表测试util_test.clj:105 预期:=将a not b c引用到符号列表[a not b c]实际:not=a not b c a not b c

但很明显,=a not b c a not b c quoted应该是真的

第二,具体测试代码:

(deftest to-symbol-list-test 
(is (= '(a (not b) c) (to-symbol-list ["a" "(not b)" "c"]))))
第三,符号列表的定义:

(defn to-symbol-list [term]
  "Converts a vector based term into a list based term
  by converting its elements into symbols recursivly"
  (postwalk
    #(if (string? %)
       (symbol %)
       (reverse (into '() %)))
    term))
该函数甚至应该转换嵌套向量。这是一个例子,其他函数以同样的方式运行。我猜它可能是由不同的类型引起的。例如,list vs lazy seq和我比较了lazy函数而不是数据,但是类型似乎是正确的。在答复中,我得到:

(type (to-symbol-list ["a" "(not b)" "c"]))
=> clojure.lang.PersistentList
似乎to-symbol列表不会将b字符串变成符号,而不是嵌套列表。要解决这个问题,您需要重构该函数以将parens考虑在内。比方说,如果它看到字符串的第一个符号,它会递归地调用自己,将结果附加到某种累加器中。顺便说一下,SICP中充满了这样的练习。

to symbol list返回一个包含3个符号的列表,而不会递归地处理嵌套的数据结构。不幸的是,第二个符号打印的数据结构与您期望的正确解析的数据结构相同。我认为在这种情况下,最好使用clojure.edn/read-string,它将按照我的预期解析您的数据结构

(defn to-symbol-list [list-of-strings]
  (map edn/read-string list-of-strings))

(to-symbol-list ["a" "(not b)" "c"])
另外,作为将来帮助诊断此类问题的提示,您可以将额外的参数传递给clojure.test/is,它将在出现故障时打印出来。这可能是函数调用的结果,如:

(ns to-symbols-test
  (:require [clojure.edn :as edn]
            [clojure.test :refer [deftest is are testing] :as t]
            [clojure.data :as data]
            [clojure.pprint :as pp]))

(defn to-symbol-list [l]
  (map edn/read-string l))

(defn diff [a b]
  (with-out-str (pp/pprint (take 2 (data/diff a b)))))

(deftest test-to-symbol-list
  (testing "to-symbol-list should convert recursively"
    (let [expected '(a (not b) c)
          result   (to-symbol-list ["a" "(not b)" "c"])]
      (is (= expected result (diff expected result))))))

我想你是掉进了符号而不是BYO的陷阱。你是对的,这就是问题所在,谢谢:非常感谢你的详细回答和diff的线索。将你的函数与我的函数合并解决了评估为真的问题。合并,因为使用recursive,我不是指在字符串中向下,而是甚至分析如下内容:[或[而不是a b c][和a非b c][和a b非c][和a b c][和a b c][]