#common-lisp #sbcl
#common-lisp #sbcl
Вопрос:
У меня есть куча констант, которые я хочу иметь тип (unsigned-byte 8)
.
(declaim (type '(unsigned-byte 8) c0 c1 ))
(defconstant c0 #x0)
(defconstant c1 #x10)
Но объявление, похоже, не помогает, учитывая, что при вводе (type-of c0 )
оно возвращает BIT
(или целое число, в зависимости от значения), что явно не то, что я хочу.
Итак, как я могу указать тип для констант?
Обновление Как оказалось, вопрос — пока еще вопрос — не был основной причиной моих проблем. В (make-array '(2) ...
части, которая вызвала ошибки о «несовместимых типах», я ввел для списка initial-contents
в кавычках, где я должен был поместить список «перечисленных». НЕПРАВИЛЬНО: '( c0 c1 )
, ПРАВИЛЬНО: (list c0 c1 )
.
Учитывая, что я все еще ассоциирую переменные вместо значений с типами в своем уме, я не мог интерпретировать значение сообщений об ошибках, исходящих из этого.
Итак, в принципе, я бы удалил вопрос, если бы система позволила мне.
Ответ №1:
Типы в Common Lisp — это на самом деле просто наборы значений. Любое значение может иметь бесконечное количество типов.
Например, число 1 относится к типу bit
(который является псевдонимом для (integer 0 1)
). Он также имеет тип (integer 0 2)
или (integer -47 234)
. Это даже типа (or string null (integer 0 277))
. Итак, когда вы спрашиваете (type-of 1)
, каким должен быть ответ?
Реализации Lisp знают о некоторых встроенных типах. Обычно они возвращают наиболее ограниченный из тех типов, которые, как они знают, содержат значение. Если в вашей реализации Lisp была специальная обработка чисел в базе 5, она может возвращать (integer 0 5)
(или псевдоним этого) для 2 .
Так вот почему CLHS говорит, что он возвращает спецификатор типа, а не тип. Он также указывает, что он должен возвращать что-то разумное (посмотрите там).
Ваша речь идет о названной константе c0
, но type-of
вызов не видит эту константу, он видит только значение, исходящее из нее (подумайте о шагах оценки). Так что декламация здесь не может иметь эффекта.
Если вы хотите ограничить тип значения на лету, вы можете использовать the
или check-type
.
Ответ №2:
(type-of c0 )
не возвращает объявленный тип переменной или константы. Он возвращает динамический тип объекта, который является значением c0
.
При объявлении типа вы объявили тип идентификатора константы. На самом деле последствия этого зависят от конкретной реализации. SBCL будет использовать это объявление типа.
Но вам нужно понимать разницу между статическими объявлениями типов с использованием DECLAIM , DECLARE и т. Д. И динамическими типами, такими как типы, используемые в TYPE-OF, TYPE-P , параметр типа элемента MAKE-ARRAY , …
Комментарии:
1. Итак, ответ «я не могу»? Когда я пытаюсь инициализировать массив с этими постоянными значениями, я получаю сообщения об ошибках, что тип константы несовместим с типом элементов массива:
(make-array '(2) :element-type (unsigned-byte 8) :initial-contents (list c0 c1 ))
что, в конечном итоге, и является моей целью.2. @bittickler: вам нужно отредактировать свой вопрос, чтобы добавить к нему. Бесполезно обсуждать фрагменты кода, имеющие синтаксические проблемы (ваш тип не указан в кавычках) и без фактических сообщений об ошибках в содержимом.