Clojure:正在评估的返回值
*简单问题:为什么此函数在求值时抛出异常?*Clojure:正在评估的返回值,clojure,classcastexception,Clojure,Classcastexception,*简单问题:为什么此函数在求值时抛出异常?* 如果字符串中存在重复项,则在查找重复项时会引发类强制转换异常 在字符串没有重复项的情况下,将抛出NullPointerException *代码* 您的问题是(=0(count str in))从未更改,因此您最终尝试在nil上首先调用。[EDIT:我错了,您的代码实际上是按原样工作的——if语句只是一个不可操作的语句。我希望您喜欢这个答案的其余部分。] 相反,您应该在recur中的list Rem上调用next(而不是rest),并在if测试中
- 如果字符串中存在重复项,则在查找重复项时会引发类强制转换异常
- 在字符串没有重复项的情况下,将抛出NullPointerException
您的问题是
(=0(count str in))
从未更改,因此您最终尝试在nil
上首先调用。[EDIT:我错了,您的代码实际上是按原样工作的——if语句只是一个不可操作的语句。我希望您喜欢这个答案的其余部分。]
相反,您应该在recur
中的list Rem
上调用next
(而不是rest
),并在if
测试中直接使用list Rem
,使用next
的属性为空序列返回nil。下面是我将如何重写您的代码:
(defn first-duplicate [in]
(loop [seen #{}
remain (seq in)]
(when-let [[head & tail] remain]
(if (contains? seen head)
head
(recur (conj seen head) tail)))))
变化:
- 小写名称
- 无需在
next
或rest的输出上调用seq
- 对于集合,
包含?
(检查键是否存在)比某些快(对元素运行谓词,直到某个元素生成真实值)
- 集合文字
- 在测试失败时使用
when
返回nil
- 当让
解构并绑定第一个字符和其余字符时,使用
风格变化:
- 名称更改为不太具体(例如,不限于字符串)
- 更改循环局部变量的顺序,使递归看起来更像结构递归
- 将循环局部变量放在单独的行上
这是一个有点奇怪的问题的最佳答案。最终的问题是,由于其他一些问题,我将函数调用封装在repl的另一个闭包中。我同意使用when-let构造显然更好。我喜欢这里编写的最终函数,但是关于rest/next的建议是你能给出的最糟糕的建议,所以幸运的是,该函数既不使用rest也不使用next。接下来是返回nil的函数;rest将返回一个空的seq(这是真实的)。我不应该被允许在不首先通过REPL运行示例的情况下谈论rest和next。我有一半的时间会把它们颠倒过来。。。
(defn first-duplicate [in]
(loop [seen #{}
remain (seq in)]
(when-let [[head & tail] remain]
(if (contains? seen head)
head
(recur (conj seen head) tail)))))