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

CompilerException java.lang.IllegalArgumentException: recur 参数闪回原始局部:x 不匹配原始值,有:Object,需要:long,编译:(NO_SOURCE_PATH:1:1)
`

7 答案

0
by

评论由: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
by

评论由:bronsa

类似的项目 http://dev.clojure.org/jira/browse/CLJ-701

0
by

评论由: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 报告)
...