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

欢迎!请查看关于页面以获取有关如何工作的更多信息。

0 点赞
Clojure
已关闭

问题
在调用Java(或内联函数)时,如果参数都是原始类型,则不会使用宽泛转换来定位合适的重载方法/构造函数。

示例

`user=> (Integer. (byte 0))
java.lang.IllegalArgumentException: No matching ctor found for class 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 时
支持相同类别的基本数值类型 widening 转换(这比 Java 严格,更有 Clojure 风格)
* 编译时支持通配符匹配(即,您不需要为避免反射而为每个参数提供类型提示)。

这还为基础添加更多功能提供支持,例如 CLJ-666。

0 点赞

评论者:ataggart

它在原地进行了文档说明,但以下是 reflector 查找方法时使用的转换规则

  1. 按类型
    **** 对象到祖先类型
    • 原始类型到同一数值类别中更宽的原始类型(新特性)
  2. 装箱
    • 装箱数字到其原始类型
    • 装箱数字到同一数值类别中更宽的原始类型(新特性,用于 Short 和 Byte 参数)
      **** 原始类型到其装箱值
    • 原始类型到 Number 或 Object(新特性)
  3. 强制转换
    • long 到 int
    • double 到 float
0 点赞

评论者:ataggart

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

0 点赞

评论者:ataggart

为 reflector 重组创建了 CLJ-792。

0 点赞

评论者:stuart.sierra

prim-conversion-update-1.patch 在 f5bcf64 之后不再适用。

CLJ-792 是否现在是此条目的先决条件?

0 点赞

评论者:ataggart

是的,在原补丁被认为“太大”之后。

在这么长时间没有收到 TPTB 的回复之后,您现在可以取消这两个条目。

0 点赞

评论者:jafingerhut

再次,不确定这是否有任何帮助,但从2012年2月20日开始,我在Clojure的头部进行测试,应用了CLJ-792附带clj-792-reorg-reflector-patch2.txt补丁,然后应用了这个ticket附加的clj-445-prim-conversion-update-2-patch.txt补丁,结果编译并通过了除了2个测试以外的所有测试。我不知道这些失败是否容易修复,或者是否可能由于这些补丁引入了问题。

0 点赞

评论者:bronsa

到1.7.0-alpha5版本,ticket描述中的两个示例在没有异常/反射警告的情况下运行。

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)
...