请在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.3beta中。我们将在未来的版本中重新审视。

0

评论者:ataggart

为了更好地解释更改,我创建了两个补丁,每个补丁包含多个可隔离的增量提交

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

prim-conversion.patch: 依赖于上面的修改。改变方法/构造函数的解决过程
更符合Java的解决方式,尤其是调用1.5以下版本的API时 增加了对同一类别的基本数字类型扩展转换的支持(这比Java更严格,更符合clojuresque风格)
在编译时添加对通配符匹配的支持(也就是说,您不需要为避免反射而对每个参数进行类型提示)。

这还为添加更多特性提供了基础,例如CLJ-666。

0
by

评论者:ataggart

它在现场有文档说明,但这里列出了反射器查找方法所使用的转换规则

  1. 按类型
    **** 将对象转换为祖先类型
    • 基本类型到同一数字类别的基本类型更宽的类型(新功能)
  2. 装箱
    • 装箱的数字到其基类
    • 装箱的数字到同一数字类别更宽的基本类型(新功能,用于Short和Byte参数)
      **** 将基本类型转换为装箱值
    • 基本类型到Number或Object(新功能)
  3. 强制类型转换
    • long类型转为int类型
    • double类型转为float类型
0
by

评论者:ataggart

prim-conversion-update-1.patch适用于当前master。

0
by

评论者:ataggart

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

0
by

由:stuart.sierra发表的评论

prim-conversion-update-1.patch从f5bcf64版本开始不再适用。

CLJ-792现在是此票证的先决条件吗?

0
by

评论者:ataggart

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

在此之后再无行动的情况发生,您可以任意取消这两个ticket。

0

评论由:jafingerhut 提交

再次,不确定这对您是否有所帮助,但我已从 Clojure head 于 2012 年 2 月 20 日起进行测试,应用了 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报告)
...