Как я могу ввести подсказку в массив?
У меня есть следующая запись:
(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) есть некоторые улучшения, так что переменные экземпляра и т.д. могут быть выбраны как примитивные типы, основанные на типе намека.