2010-09-15 4 views
14

Je l'enregistrement suivant:Comment puis-je taper un tableau?

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

Comment puis-je spécifier samples être un double tableau?

J'utilise clojure 1.2.0

Edit:

@dreish Je reçois la sortie suivante quand je l'appelle (show Signal) après les changements 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 

Je sais que L'indication de type non-primitif est juste utilisée pour éviter la réflexion. De http://clojure.org/datatypes

  • Notez qu'actuellement un indice de type d'un type non primitif ne sera pas utilisée pour contraindre le type de champ, ni le constructeur arg, mais sera utilisé pour optimiser son utilisation dans les méthodes de classe

Merci à tous!

Répondre

18

Comme ceci:

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

Rich Hickey ajouté un certain temps:

Ajout des notes de type spécial pour les tableaux primitifs - #^ints, #^chars, #^désire ardemment, #^doubles

Voir http://clojure.org/news pour une discussion sur comment cela fonctionne.

Je n'ai pas d'environnement Clojure avec moi pour voir si c'est toujours la meilleure façon de le faire. Je suppose que la #^syntaxe a été mis à jour^ainsi que tous les autres conseils de type à Clojure à 1,2

Edit: Un autre blog sur elle: http://asymmetrical-view.com/2009/07/02/clojure-primitive-arrays.html

5

Je suis d'accord avec la réponse de Levand sur lequel pointe le type d'utilisation, mais vous pouvez vérifier si defrecord utilise réellement ces indications de type. Sur mon installation (aussi 1.2.0), ce n'est pas le cas.

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] 

Comme vous pouvez le voir, les arguments du constructeur (38) et les variables membres (41-43) sont juste Object s. (Les tableaux sont des références de toute façon, mais il sera agréable d'être un jour capable de stocker des numéros sans emballage dans un enregistrement une fois cette fonctionnalité est mise en œuvre.)

4

Pour élaborer sur ce dreish a écrit:

Comme il est actuellement mis en œuvre (1.2), les indications de type ne se manifestent pas dans l'API (variables d'instance, signatures constructeur/méthode), mais sont plutôt utilisées pour éliminer les appels de réflexion dans la portée lexicale. Par exemple:

 
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 question qui reste est la boxe des nombres primitifs, mais un double tableau est-un objet, donc pas de problème.Cela dit, je crois qu'il y a quelques améliorations dans la branche master (1.3), de sorte que les variables d'instance, etc., peuvent être émises en tant que types primitifs basés sur l'indication de type.

Questions connexes