Как я могу напечатать подсказку массив? - PullRequest
17 голосов
/ 15 сентября 2010

У меня есть следующая запись:

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

Как мне указать samples как двойной массив?

Я использую clojure 1.2.0

Редактировать:

@ dreish Я получаю следующий вывод при вызове (show Signal) после изменений от 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

Я знаю, что намеки не примитивного типа просто используются, чтобы избежать отражения. От http://clojure.org/datatypes

  • обратите внимание, что в настоящее время подсказка типа не примитивного типа не будет использоваться для ограничения типа поля или аргумента конструктора, а будет использоваться для оптимизации его использования в методах класса

Спасибо всем!

Ответы [ 3 ]

19 голосов
/ 15 сентября 2010

Как это:

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

Rich Hickey добавил это некоторое время назад:

Добавлены специальные подсказки типов для примитивных массивов - # ^ ints, # ^ float, # ^ longs, # ^ doubles

См. http://clojure.org/news для обсуждения того, как это работает.

У меня нет среды Clojure, чтобы посмотреть, является ли это все еще лучшим способом сделать это. Я предполагаю, что синтаксис # ^ был обновлен до ^ вместе со всеми другими подсказками типов в Clojure в 1.2

Редактировать: еще один пост в блоге: http://asymmetrical -view.com / 2009/07/02 / clojure-primitive-arrays.html

5 голосов
/ 16 сентября 2010

Я согласен с ответом 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,(Массивы в любом случае являются ссылками, но было бы неплохо, чтобы когда-нибудь эта функция могла сохранять распакованные номера в записи, как только эта функция будет реализована.)

4 голосов
/ 16 сентября 2010

Чтобы уточнить, что написал дриш:

Поскольку в настоящее время реализовано (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

Остается проблема с упаковкой простых чисел, хотя двойной массив является объектом, так что не беспокойтесь.

Тем не менее, я считаю, что есть некоторые улучшения в основной ветке (1.3), такие как переменные экземпляра и т. Д., Которые могут быть переданы как примитивные типы на основе подсказок типов.

...