Clojure 为什么这种类型的注释会失败?
我想了解为什么我不能在clojure中向这个点积函数添加返回类型注释Clojure 为什么这种类型的注释会失败?,clojure,Clojure,我想了解为什么我不能在clojure中向这个点积函数添加返回类型注释 (defn dot3 "3d vector dot product" ^double [^doubles [u0 u1 u2] ^doubles [v0 v1 v2]] (+ (* u0 v0) (* u1 v1) (* u2 v2))) 在下面的日志中,您可以看到减法的注释工作正常,如果我删除^double返回类型注释,它也可以工作。但是,调用上述代码时会产生错误: user=> (
(defn dot3
"3d vector dot product"
^double [^doubles [u0 u1 u2]
^doubles [v0 v1 v2]]
(+ (* u0 v0) (* u1 v1) (* u2 v2)))
在下面的日志中,您可以看到减法的注释工作正常,如果我删除^double
返回类型注释,它也可以工作。但是,调用上述代码时会产生错误:
user=> (dot3 [4 5 6] [1 2 3])
ClassCastException user$dot3 cannot be cast to clojure.lang.IFn$OOD user/eval3487 (form-init8441686871120943013.clj:1)
提前感谢,
--罗杰
您提供的类型批注与您为函数指定参数的方式不兼容 解构会阻止正确的代码被编译。事实证明,这是当前Clojure版本中的一个bug,但将在1.7版本中修复 以下版本工作正常:
(defn dot3
"3d vector dot product"
^double [^doubles u
^doubles v]
(+ (* (aget u 0) (aget v 0))
(* (aget u 1) (aget v 1))
(* (aget u 2) (aget v 2))))
user=> (dot3 (double-array [4.0 5.0 6.0]) (double-array [1.0 2.0 3.0]))
32.0
仅供参考当您提供不正确的注释时,编译时的反射警告将消失,但您仍然需要为运行时反射支付CPU成本,因为类型错误。对于
^double
的注释,参数的类型应为“[D;”
(double的基本数组),而不是Long的PersistentVector。谢谢。这为我清除了它。但我不知道如何从编译错误中找出这一点……我希望它失败(或警告)如果我做了一些愚蠢的事情,比如使用PersistentVector而不是primitive array…有一个primitive math lib可以帮助——是的,Clojure错误/编译消息通常很难破译。接下来:看起来这实际上是您发现的一个bug,在1.7中得到了修复。这个bug修复是否意味着(dot3[4.0 5.0 6.0][1.0 2.0 3.0])以及1.7中的(dot3(双数组[4.0 5.0 6.0])(双数组[1.0 2.0 3.0])?使用aget
,而不是get
,在基本数组中查找内容,否则类型提示将被浪费。
(defn dot3
"3d vector dot product"
^double [^doubles u
^doubles v]
(+ (* (aget u 0) (aget v 0))
(* (aget u 1) (aget v 1))
(* (aget u 2) (aget v 2))))
user=> (dot3 (double-array [4.0 5.0 6.0]) (double-array [1.0 2.0 3.0]))
32.0