Обычная хеш-таблица Lisp с акцентированными символами в качестве ключей - PullRequest
3 голосов
/ 30 июня 2019

Я пытаюсь создать хеш-таблицу в Common Lisp для хранения символов в качестве ключей, но хеш-таблица не работает, если я использую символы с акцентом.Требуется только один возможный ключ с акцентами.

В этом примере я добавляю 5 ключей и вижу, что в хеш-таблице показано 5 элементов, затем добавляю еще 5 с акцентами, а в таблице показано 6 элементов, а затем добавляется еще один «нормальный »5 элементов и размер достигает 11 (как и ожидалось).

Что происходит?И как я могу решить это?

(defparameter *h* (make-hash-table))
(setf (gethash #\A *h*) #\A)
(setf (gethash #\E *h*) #\A)
(setf (gethash #\I *h*) #\A)
(setf (gethash #\O *h*) #\A)
(setf (gethash #\U *h*) #\A)
(hash-table-count *h*)
(setf (gethash #\á *h*) #\A)
(setf (gethash #\é *h*) #\A)
(setf (gethash #\í *h*) #\A)
(setf (gethash #\ó *h*) #\A)
(setf (gethash #\ú *h*) #\A)
(hash-table-count *h*)
(setf (gethash #\a *h*) #\A)
(setf (gethash #\e *h*) #\A)
(setf (gethash #\i *h*) #\A)
(setf (gethash #\o *h*) #\A)
(setf (gethash #\u *h*) #\A)
(hash-table-count *h*)

Ответы [ 2 ]

4 голосов
/ 01 июля 2019

Из руководства SBCL :

On non-Unicode builds, the default external format is :latin-1.

Вы хотите использовать UTF-8.Так что делайте то, что говорится в руководстве, и настройте свою среду, когда вы вызываете SBCL:

$ LANG=C.UTF-8 sbcl --noinform --no-userinit --eval "(print (map 'string #'code-char (list 97 98 246)))" --quit
"abö"
$ LANG=C sbcl --noinform --no-userinit --eval "(print (map 'string #'code-char (list 97 98 246)))" --quit
"ab?"

Если вы используете SLIME или Sly из Emacs, есть способ настроить его в вашем init:

(setq sly-lisp-implementations
      '((sbcl ("/opt/sbcl/bin/sbcl") :coding-system utf-8-unix)))

Затем используйте функцию проверки нормального состояния, например char=.Вы должны использовать наиболее конкретный предикат всякий раз, когда это возможно, по моему мнению.char-equal является регистронезависимой версией.

Хитрое руководство, хотя приведенный выше фрагмент работает и на SLIME, как slime-lisp-implemetations

Как отмечено в комментарии @Мануэль, если ваша переменная LANG и друзья не используют UTF-8, то вы обречены. Посмотреть этот вопрос

2 голосов
/ 01 июля 2019

Если по какой-либо причине вы не можете изменить значение по умолчанию SBCL внешний формат , вы всегда можете использовать #\LATIN_SMALL_LETTER_A_WITH_ACUTE и т. Д.

...