2010-09-15 21 views
14

tengo el siguiente registro:¿Cómo puedo tipear una matriz?

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

¿Cómo puedo especificar samples ser una matriz doble?

estoy usando clojure 1.2.0

Editar:

@dreish Me da la siguiente salida cuando llamo (show Signal) después de los cambios de Levand:

[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 

Sé que sugerencias de tipo no primitivo solo se utilizan para evitar la reflexión. De http://clojure.org/datatypes

  • nota que en la actualidad un tipo de indicio de un tipo no primitivo no será utilizado para restringir el tipo de campo ni el arg constructor, pero se puede utilizar para optimizar su uso en los métodos de la clase

¡Gracias a todos!

Respuesta

18

De esta manera:

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

Rich Hickey añadió esta hace un tiempo:

Añadido indicaciones especiales del tipo de matrices primitivas - #^enteros, #^flotadores, #^anhela, #^duplica

Para más información sobre cómo funciona, consulte http://clojure.org/news.

No tengo un entorno Clojure conmigo para ver si esta sigue siendo la mejor manera de hacerlo. Asumo la #^sintaxis fue actualizada^junto con todos los otros consejos de tipo en Clojure en 1.2

Editar: Otro post blog en él: http://asymmetrical-view.com/2009/07/02/clojure-primitive-arrays.html

5

estoy de acuerdo con la respuesta de Levand en el que toque el tipo de usar, pero es posible que desee comprobar si defrecord realmente utiliza estas sugerencias de tipo. En mi instalación (también 1.2.0), no es así.

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] 

Como se puede ver, los argumentos de constructor (38) y las variables miembro (41-43) siguen siendo tan Object s. (Las matrices son las referencias de todos modos, pero será agradable ser algún día capaz de almacenar números sin caja en un registro, una vez que la función se implementa.)

4

dar más detalles sobre lo que dreish escribió:

ya que se implementa actualmente (1.2), las sugerencias de tipo no se manifiestan en la API (variables de instancia, firmas de constructor/método), sino que se utilizan para eliminar llamadas de reflexión dentro del alcance léxico. Por ejemplo:

 
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 

La cuestión que queda es el boxeo de los números primitivos, a través de una matriz doble es un objeto-, por lo que no hay preocupaciones.

Dicho esto, creo que hay algunas mejoras en la rama maestra (1.3) de modo que las variables de instancia, etc., se pueden emitir como tipos primitivos basados ​​en el tipo de alusión.

Cuestiones relacionadas