Tech Talk 让技术发出声音
RSS

SBCL的repl中使用UTF-8

SBCL是什么

SBCL是Common Lisp的一个实现,也是笔者比较推荐的一个实现,因为看到著名企业Grammarly也在使用这个实现,并且该实现得到了Google的程序员的支持。

出现了什么问题

SBCL对UTF8的支持一直很好,但是在编写一个东西的时候出现了个奇怪的东西,通过SBCL的的repl存储到redis中的数据,并不是UTF-8的,并且是完全错误的。

解决问题

输入输出编码检查

在SBCL的repl中使用下面的代码


(stream-external-format *standard-output*)
(stream-external-format *standard-input*)
sb-impl::*default-external-format*

得到的结果是(:ASCII :REPLACEMENT #\?),说明默认的输入输出的格式是ASCII的

解决方法

是用了下面这段代码


(defun set-default-external-format (external-format)
  (assert (sb-impl::find-external-format external-format))
  (setf sb-impl::*default-external-format* external-format)
  (with-output-to-string (*error-output*)
    (setf sb-sys:*stdin*
          (sb-sys:make-fd-stream 0 :name "standard input" :input t :buffering :line))
    (setf sb-sys:*stdout*
          (sb-sys:make-fd-stream 1 :name "standard output" :output t :buffering :line))
    (setf sb-sys:*stderr*
          (sb-sys:make-fd-stream 2 :name "standard error" :output t :buffering :line))
    (setf sb-sys:*tty* 
        (make-two-way-stream sb-sys:*stdin* sb-sys:*stdout*)) 
    (princ (get-output-stream-string *error-output*) sb-sys:*stderr*)))

将SBCL的repl输入输出设定为了UTF-8。