【发布时间】:2017-07-27 16:07:56
【问题描述】:
我有时会编写 java 方法,特别是对于基元/数组操作,我总是纠结于如何在 Clojure 1.8 下使用类型提示。我看到了一些线程,但考虑到它们已在 2 年多前发布,它们(也许?)已经过时了。
我将举一个基本的例子来说明我的观点(我知道这个例子有点毫无意义)。在这里,我想将两个 double 相加并返回一个 double。
这是一个Java方法:
public static double add (double a, double b) {
return a + b;
}
然后我想要一个 Clojure 包装器:
版本 1
(defn d+ ^double
[^double a ^double b]
(Doubles/add a b))
第 2 版
(defn d+ ^double
[^double a ^double b]
(Doubles/add ^double a ^double b))
第 3 版
(defn d+ ^double
[^double a ^double b]
(Doubles/add (double a) (double b)))
我不知道在哪里放置类型提示以及如何放置它们。我的印象是(double x) 效率较低,因为它是一个函数(也许我错了?)。
那么在 body 函数内部和外部给出提示有什么区别呢?
或者也许这些提示是不必要的,因为 Java 类中只有一种方法? 我看不到逻辑,所以我通常使用版本 1 或 3(越多越好?)。
请注意,对于此示例,Clojure + 总是更快
【问题讨论】:
-
*warn-on-reflection*标志将有助于这种探索。只需将其设置为 true,编译器就会发出无法选择所需方法重载并需要提示的情况。 -
谢谢我已经测试过了,最后不需要任何提示。你知道为什么这个函数比较慢,因为它只适用于 double 吗?我的直觉是互操作意味着一些隐藏的操作/成本,因此 Java 互操作只有在函数成本高(如大算法)或函数在 Clojure 中不存在时才值得。
-
@leetwinski 原始类型提示与反射警告无关,它们是针对对象的。原始提示用于避免装箱的性能。更好的是在你的 clojure 文件请求时启用
(set! *unchecked-math* :warn-on-boxed)。
标签: clojure type-hinting