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

欢迎!有关如何使用本服务的更多信息,请参阅 关于 页面。

0
Clojure
已关闭

问题
在调用 Java 方法(或在内联函数中),如果参数和参数都是基本类型,则定位重载的方法/构造函数时不使用扩展转换。

示例

`user=> (Integer. (byte 0))
java.lang.IllegalArgumentException: 未找到类 java.lang.Integer 的匹配构造函数 (NO_SOURCE_FILE:0)

上述情况发生是因为没有 Integer(byte) 构造函数,尽管它应该与 Integer(int) 匹配。

user=> (bit-shift-left (byte 1) 1)
Reflection warning, NO_SOURCE_PATH:3 - call to shiftLeft can't be resolved.
2` In the above, a call is made via reflection to Numbers.shiftLeft(Object, Object) and its associated auto-boxing, instead of directly to the perfectly adequate Numbers.shiftLeft(long, int). Workarounds:
Explicitly casting to the formal type. Ancillary benefits of fixing:
It would also reduce the amount of method overloading, e.g., RT.intCast(char), intCast(byte), intCast(short), could all be removed, since such calls would pass to RT.intCast(int).
关闭时的注释:作为 CLJ-2843 的副作用在 1.11.3 和 1.12.0-alpha10 中修复

26 答案

0

评论者:redinger

这项工作太大,目前无法纳入 1.3 测试版。我们将将其纳入未来的版本。

0

评论者:ataggart

为了更好地理解这些更改,我将它们分成两个补丁,每个补丁都包含多个可隔离的增量提交

reorg-reflector.patch: 将编译器的反射/调用代码移至 Reflector,并消除冗余代码。结果是单个代码库用于解析方法/构造函数,这将允许在不进行过多外部协调的情况下修改该机制。此包含无行为变化。

prim-conversion.patch: 依赖上述修改。改变方法/构造函数解析过程
更符合Java解析方式,尤其是在调用1.5之前的API时,增加了对同种类原始数值的拓宽转换支持(这比Java更严格,更具Clojure风格)
增加了在编译时支持通配符匹配(即,您不必为每个参数类型提示以避免反射)。

这还提供了一个添加更多功能的基础,例如CLJ-666。

0

评论者:ataggart

这部分已经在原地进行了文档说明,但以下是反射器使用以查找方法的重构规则

  1. 通过类型
    **** 对象到祖先类型
    • 原始数据类型到同类型更宽的原始数值类型(新功能)
  2. 装箱
    • 装箱数值到其对应的原始数据类型
    • 装箱数值到同类型更宽的原始数值类型(针对Short和Byte参数的新特性)
      **** 原始数据类型到其对应的装箱值
    • 原始数据类型到Number或Object(新功能)
  3. 类型转换
    • long转换成int
    • double转换成float
0

评论者:ataggart

prim-conversion-update-1.patch适用于当前的主干分支。

0

评论者:ataggart

为反射器重构创建了CLJ-792。

0

评论者:stuart.sierra

prim-conversion-update-1.patch自版本f5bcf64起不再适用。

CLJ-792现在是此票据的一个先决条件吗?

0

评论者:ataggart

是的,在最初的修改被认为“太大”之后。

由于TPTB长时间未采取行动,现在可以自由地关闭这两个票据。

0

评论由:jafingerhut 提出

再次,不确定这有没有帮助,但我已经从 2012 年 2 月 20 日起测试 Clojure head 版本,应用了 CLJ-792 附件中的 clj-792-reorg-reflector-patch2.txt,然后应用了这个卡片附件中的 clj-445-prim-conversion-update-2-patch.txt,结果是编译通过了除了 2 个测试之外的所有测试。我不知道这些失败的修复是否简单,或者这些补丁是否引入了问题。

0

评论由:bronsa 提出

截至 1.7.0-alpha5 版本,该卡片描述中的两个例子运行时不出现异常/反射警告

user=> (set! *warn-on-reflection* true) true user=> (bit-shift-left (byte 1) 1) 2 user=> (Integer. (byte 0)) 0

0

评论由:fl00r 提出

嗨!

`
(Integer. (Long. 1))

=> 1

(Long. (Integer. 1))

=> 异常

`

https://github.com/clojure/clojure/pull/59

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