java - UnmodifiableRandomAccessList 和“包含?”的问题 功能
问题描述
我正在尝试为一个名为stensil的开源应用程序做出贡献。它是用 Clojure 编写的。
stensil
是一个在 .docx 之上工作的模板引擎。模板引擎声明了一组要在模板中使用的自定义函数。完整的函数列表很短,可以在此处查看。
我需要添加另一个自定义函数来检查列表是否包含元素。按照现有示例,我这样做了:
(defmethod call-fn "contains" [_ item items] (contains? items item))
为了测试这一点,我创建了一个 .docx 文件,其中包含以下代码段:
{%= contains(5, data) %}
和一个包含以下内容的 .json 文件:
{
"data": [9, 4, 1, 6, 3]
}
然后我像这样运行应用程序:
java -jar stencil-core-0.3.8-standalone.jar template.docx sample.json
不幸的是,在使用时,我定义的函数不起作用,抛出以下异常:
java.lang.IllegalArgumentException: contains? not supported on type: java.util.Collections$UnmodifiableRandomAccessList
看来items
是类型java.util.Collections$UnmodifiableRandomAccessList
。确实,如果我将 a 添加(println items)
到函数中,我会得到:
#object[java.util.Collections$UnmodifiableRandomAccessList 0x778ca8ef [9, 4, 1, 6, 3]]
some
我尝试通过使用函数来做不同的事情。这个答案表明它应该在大多数情况下工作。不幸的是,下面的两个变体都返回nil
:
(defmethod call-fn "contains" [_ item items] (some #{item} items))
(defmethod call-fn "contains" [_ item items] (some #(= item %) items))
我以前从未写过一行 Clojure,现在有点迷茫。我究竟做错了什么?some
将列表从 UnmodifiableRandomAccessList 转换为可以使用或contains?
可以使用的东西是否有意义?如果是,我如何对items
变量执行这种转换?
更新。尝试.contains
按照cfrick在答案中的建议使用,如下所示:
(defmethod call-fn "contains" [_ item items] (.contains items item))
这不会引发运行时错误,但输出始终是false
现在。println
调试揭示了这一点:
(defmethod call-fn "contains" [_ item items]
(println item)
(println items)
(.contains items item))
1
#object[java.util.Collections$UnmodifiableRandomAccessList 0x778ca8ef [9, 4, 1, 6, 3]]
为什么?
解决方案
上面的答案都是正确的,因为contains?
不能用于此目的的列表,而且我们正在尝试比较不同的类型。
这个特定示例中的问题是第一个参数中的数字是 a java.lang.Long
,而第二个参数中的列表包含java.math.BigDecimal
实例。这是因为默认 JSON 解析器模板在独立模式下使用将数字反序列化为 BigDecimal。
一个快速而肮脏的解决方案是在任何地方都使用字符串。
您还可以定义专门用于数字的函数的变体:
(defmethod call-fn "ncontains" [_ item items]
(boolean (some #{(double item)} (map double items))))
或将所有数字强制为同一类型:
(defmethod call-fn "contains" [_ item items]
(letfn [(norm [x] (if (number? x) (double x) x))]
(boolean (some #{(norm item)} (map norm items)))))
推荐阅读
- java - 工具栏在过渡到新片段时消失
- php - 如何在 SQL 中输出下一个日期?
- html - 引导下拉列表未扩展
- java - 有没有一种干净的方法来更改 Nimbus Jose JWT 中的默认 JWKSetCache TTL?
- amazon-web-services - AWS 数据库子网为空
- r - 如何重命名文件以使文件扩展名不出现在使用 R 的名称中
- javascript - VueJS 不在电子应用程序内的 DOM 上呈现数据
- javascript - 无法读取 null 的属性“classList”
- python - 如何正确安装 virtualenv 和 virtualenvwrapper?
- c++ - Boost bootstrap 抛出错误