Как я могу ввести подсказку в массив?

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

(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

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

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

Ответы

Ответ 1

Вот так:

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

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

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

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

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

Изменить: еще одно сообщение в блоге: http://asymmetrical-view.com/2009/07/02/clojure-primitive-arrays.html

Ответ 2

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

Ответ 3

Чтобы узнать, что написал 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

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

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