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

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

0
Java 互操作

(import 'java.io.DataOutputStream)
(import 'java.io.ByteArrayOutputStream)

(defn- ->bytes
  "将 Java 基本类型转换为字节表示形式。"
  [write v]
  (let [output-stream (ByteArrayOutputStream.)
        data-output (DataOutputStream. output-stream)]
    (write data-output v)
    (seq (.toByteArray output-stream))))

(defn int->bytes [n]
  (->bytes
    #(.writeInt ^DataOutputStream %1 %2)
    n))

(defn int->bytes-ref [n]
  (->bytes
    #(.writeInt %1 %2)
    n))

user=> (int->bytes 5)
(0 0 0 5)
user=> (int->bytes-ref 5)
(0 0 0 5)
user=> (int->bytes (inc Integer/MAX_VALUE))

IllegalArgumentException Value out of range for int: 2147483648  clojure.lang.RT.intCast (RT.java:1115)
user=> (int->bytes-ref (inc 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 报告)
...