如何键入提示数组?

时间:2010-09-15 17:37:17

标签: clojure type-hinting

我有以下记录:

(defrecord Signal [samples ^double sample-rate ^double scaling-factor])

如何指定samples为双数组?

我正在使用clojure 1.2.0

修改:

@dreish在levand发生更改后调用(show Signal)时,我得到以下输出:

[35] <init> (Object,double,double)
[36] <init> (Object,double,double,Object,Object)
[37] __extmap : Object
[38] __meta : Object
[39] sample_rate : double
[40] samples : Object
[41] scaling_factor : double

我知道暗示非原始类型只是用来避免反射。来自http://clojure.org/datatypes

  • 请注意,目前非基本类型的类型提示不会用于约束字段类型,也不会用于构造函数arg,但会用于优化其在类方法中的使用

谢谢大家!

3 个答案:

答案 0 :(得分:19)

像这样:

(defrecord Signal [^doubles samples ^double sample-rate ^double scaling-factor])

Rich Hickey暂时补充说:

  

为原始数组添加了特殊类型提示 - #^ ints,#^ floats,#^ longs,#^ double |

有关其工作原理的讨论,请参阅http://clojure.org/news

我没有Clojure环境,看看这是否仍然是最好的方法。我假设#^语法已更新为^以及1.2中的Clojure中的所有其他类型提示

编辑:关于它的另一篇博文:http://asymmetrical-view.com/2009/07/02/clojure-primitive-arrays.html

答案 1 :(得分:5)

我同意levand关于使用哪种类型提示的答案,但您可能想要检查defrecord是否实际使用这些类型提示。在我的安装(也是1.2.0)上,它没有。

user=> (defrecord Signal [^doubles samples ^double sample-rate ^double scaling-factor])
user.Signal
user=> (use '[clojure.contrib.repl-utils :only [show]])    
nil
user=> (show Signal)
===  public final user.Signal  ===

[stuff deleted]

[38] <init> (Object,Object,Object)
[39] __extmap : Object
[40] __meta : Object
[41] sample_rate : Object
[42] samples : Object
[43] scaling_factor : Object

[more stuff deleted]

如您所见,构造函数参数(38)和成员变量(41-43)仍然只是Object s。 (无论如何,数组都是引用,但有一天能够在实现该功能后将未装箱的数字存储在记录中会很好。)

答案 2 :(得分:4)

详细说明dreish所写的内容:

当前实现(1.2),类型提示不会在API中显示(实例变量,构造函数/方法签名),而是用于消除词法范围内的反射调用。例如:

user=> (set! *warn-on-reflection* true)
true
user=> (defprotocol P (foo [p]))
P
user=> (defrecord R [n] P (foo [_] (.intValue n)))
Reflection warning, NO_SOURCE_PATH:4 - reference to field intValue can't be resolved.
user.R
user=> (defrecord R [^Number n] P (foo [_] (.intValue n)))
user.R

剩下的问题是原始数字的装箱,虽然双数组是-a 对象,所以不用担心。

也就是说,我相信master分支(1.3)中有一些增强功能,可以根据类型提示将实例变量等作为基本类型发出。