2024 年 Clojure 状态调查! 分享你的想法。

欢迎!请参阅 关于 页面获取更多有关本如何工作的信息。

+1
编译器

原始函数和 recur 变量无法干净地通过 (try) 传递;它们被装箱成 Object。这导致使用原始类型的函数或循环出现反射警告。

`
user=> (set! warn-on-reflection true)
true

user=> (fn [] (loop [t 0] (recur t)))

<user$eval676$fn677 user$eval676$fn677@3d80023a>

user=> (fn [] (loop [t 0] (recur (try t))))
NO_SOURCE_FILE:1 recur 参数对原始本地变量 t 不匹配,已有:Object,需要:long
自动装箱循环参数:t

<user$eval680$fn681 user$eval680$fn681@5419323a>

user=> (fn [^long x] (recur (try x)))
NO_SOURCE_FILE:1 recur 参数对原始本地变量 x 不匹配,已有:Object,需要:long

编译器异常 java.lang.IllegalArgumentException: recur 参数对原始本地变量 x 不匹配,已有:Object,需要:long,编译:(NO_SOURCE_PATH:1:1)
`

7 答案

0

评论者:davidj

不评论最理想的用法,以下代码不会引发反射警告

`
user=> (set! warn-on-reflection true)
true
user=> (fn [] (loop [t 0] (recur (long (try t)))))

<user$eval673$fn674 user$eval673$fn674@4e56c411>

`

0

评论者:bronsa

相似问题 http://dev.clojure.org/jira/browse/CLJ-701

0

评论者:hiredman

编译器中实现的 try/catch 仅为 Expr,而不是 MaybePrimitiveExpr,看起来扩展 TryExpr 来支持 MaybePrimitiveExpr 简单超过,但实际上 recur 在语句上下文中分析其参数,导致 (try ...) 实质上像 ((fn (link: ) (try ...))) 这样的函数包装了自己,此时它是一个 invokeexpr,这要添加 maybeprimitiveexpr 更加困难,并且它与 CLJ-701 的相同案例

0

评论者:hiredman

http://dev.clojure.org/jira/browse/CLJ-701 有一个补丁我认为可以解决这个问题

0

由:alexmiller 评论

我是否应该将其复制到 CLJ-701?

0

评论者:hiredman

如果您希望 try 语句中返回上下文的修复包含在 CLJ-701 中,那么它就是重复项,如果您不确定或希望 701 保持更集中的焦点(我的补丁可能不可接受,或者可能太大而做得太多),那么它就不会是重复项。我在 CLJ-701 上的补丁中解决了这两个问题,因为我是通过 Nicola 在此处的评论来到 CLJ-701 的,同样的编译器机制可用于两者。

我认为状态取决于 CLJ-701 的状态。

0
参考:https://clojure.atlassian.net/browse/CLJ-1422(由 aphyr 报告)
...