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

欢迎!请参阅关于页面以了解此信息的工作原理。

0
Java 互操作

(导入 'java.io.DataOutputStream)
(导入 'java.io.ByteArrayOutputStream)

(定义 ->bytes
  "将 Java 基本数据类型转换为字节表示形式。"
  [写 v]
  (let [输出流 (ByteArrayOutputStream.)
      数据输出 (DataOutputStream. 输出流)]
    写入数据输出 v)
    (转化为 (.toByteArray 输出流))))

(定义 int->bytes [n]
  (->bytes
    #(写入Int ^DataOutputStream %1 %2)
    n))

(定义 int->bytes-ref [n]
  (->bytes
    #(写入Int %1 %2)
    n))

用户=> (int->bytes 5)
(0 0 0 5)
用户=> (int->bytes-ref 5)
(0 0 0 5)
用户=> (int->bytes (+ Integer/MAX_VALUE))

IllegalArgumentException Int值超出范围:2147483648  clojure.lang.RT.intCast (RT.java:1115)
用户=> (int->bytes-ref (+ Integer/MAX_VALUE))
(-128 0 0 0)


看起来,对 DataOutputStream 进行类型注解导致字节码调用 RT.intCast,因为它抛出异常,因为值太大。在反射情况下,我们在运行时找到 writeInt 方法,然后不调用 RT.intCast,而是允许长型向下转换而不进行范围检查。

似乎我们应该在这两种情况下都调用 RT.intCast?

1 答案

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