2024 Clojure 调查问卷!中分享您的想法。

欢迎!请访问关于页面了解更多此网站的信息。

0
ClojureScript

在扩展记录的协议时,在某些情况下递归方法永远不会终止。

`
(defrecord R [a])

(defprotocol P
(f [x]))

(extend-protocol P
R
(f [x]

(if x
  (recur nil)
  x))

default
(f [x]

(if x
  (recur nil)
  x)))

(prn (f 1)) ; #1
(prn (f (R. 1))) ; #2
`

{{prn}} 调用 #1 打印 {{nil}},如预期,但 {{prn}} 调用 #2 永远不终止。

看起来编译器在 {{while}} 循环内部为 {{this}} 创建了一个变量,使得对 "{{x}}" 的测试始终实际上是测试 {{this}},而应该是测试通过 {{recur}} 调用传入的 {{x}} 的值。

注意,我正在测试 ClojureScript 1.8.51。上面 "影响版本" 字段只给出了 1.7.228 作为最新版本。

3 个答案

0

评论者:bstiles

实际上,"当应该是测试 x 通过 recur 调用传入的值时,实际上总是在测试 'this'" 只有在 x 表示的值的类型保持一致时才是正确的。例如在示例中,当类型发生变化时,调用应该派发到正确匹配的方法实现。

这似乎在 Clojure 中表现正常。

0

评论者:dnolen

与 Mike Fikes 确认,即使在 recur 增强的 master 版本上,这仍然是一个问题。

0
参考: https://clojure.atlassian.net/browse/CLJS-1644(由 alex+import 提报)
...