arrays - 为什么与 'def' 绑定(bind)的 int 数组在 Clojure 中接受 Long 值?

标签 arrays clojure interop long-integer

我注意到,如果我 def 一个 int 数组并用 Long 设置数组中的一个元素,那么就不会出现任何提示。但是,如果我在 let block 中绑定(bind) int 数组并设置一个具有 Long 的元素,则会引发 IllegalArgument 异常。有人可以帮我理解这是为什么吗?

下面的代码演示了这种差异。我在 Clojure 1.8 和最新的 beta 版本 1.9 中进行了尝试,并得到了这些结果。

(def a (int-array 10))
(aset a 0 Long/MAX_VALUE) ;; sets first element to -1

(let [b (int-array 10)]
  (aset b 0 Long/MAX_VALUE)) ;; throws java.lang.IllegalArgumentException: Value out of range for int:

最佳答案

造成这种差异的原因是 let 中发生类型推断,而不是 def 中。您可以通过使用类型提示来切换情况来验证这一点:

(def ^"[I" a (int-array 10))
(aset a 0 Long/MAX_VALUE)
;; throws java.lang.IllegalArgumentException: Value out of range for int:

(let [^Object b (int-array 10)]
  (aset b 0 Long/MAX_VALUE))
;; sets first element to -1

或者,另一种选择:

(def a (int-array 10))
(aset ^"[I" a 0 Long/MAX_VALUE)
;; throws java.lang.IllegalArgumentException: Value out of range for int:

(let [b (int-array 10)]
  (aset ^Object b 0 Long/MAX_VALUE))
;; sets first element to -1

这是因为Clojure inlines calls to aset when possible ,其中包括所有这些情况,但内联静态方法调用 has many overloads .

关于arrays - 为什么与 'def' 绑定(bind)的 int 数组在 Clojure 中接受 Long 值?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45270009/

相关文章:

interop - 是否可以对互操作程序集进行代码覆盖率分析?

c++ - 文件输出中出现错误字符

javascript将一个对象推送到数组对象但其他对象受到影响

clojure - 我们如何在 Clojure 中进行左右折叠?

c# - C# 中从 native C++ 继承并将继承类向后传递给 C++

c# - x64 机器出现 "Class not registered"错误

c++ - 实现 [B,C]=f(A) 语法(函数 f 作用于具有两个或多个输出数组的数组)

php 每个循环插入数据两次,而不是按预期插入每一行

docker - 使用 deps.edn 在容器中安装依赖项

Clojure:列表的最大值