Common Lisp格式的可重复的一对一问题

Reb*_*bin 5 common-lisp

format的标签~VT表现不同,取决于换行~%是在行的开头还是结尾,我想知道原因.不同之处在于,当换行位于行的末尾时,在第一个实例中似乎只有 制表位的额外空格.以下示例说明.示例中唯一的区别在于格式控制字符串:它"~%~A~VT= ~A"在第一个示例中,"~A~VT= ~A~%"在第二个示例中.

例1:输出行开头的换行符

(let ((sb (make-array 0
                :element-type 'character
                :adjustable t
                :fill-pointer 0)))
           (mapcar (lambda (line)
                     (format sb "~%~A~VT= ~A" line 10 42))
                   '(a abcd asdf foobar g november))
           sb)
"
A        = 42
ABCD     = 42
ASDF     = 42
FOOBAR   = 42
G        = 42
NOVEMBER = 42"
Run Code Online (Sandbox Code Playgroud)

这里的行为符合预期.

例2:输出行末尾的换行符

在这个例子中需要注意的是第一行,

A         = 42
Run Code Online (Sandbox Code Playgroud)

其中还有一个空格,而不是示例1中的相应行:

A        = 42
Run Code Online (Sandbox Code Playgroud)

由于领先的双引号,这有点难以看出,这就是为什么我把它剪掉了:帮助你更好地看待它们.这在更大的例子中是可重复的,并且是一个MVE从更大的程序中剥离出来的.

(let ((sb (make-array 0
                :element-type 'character
                :adjustable t
                :fill-pointer 0)))
           (mapcar (lambda (line)
                     (format sb "~A~VT= ~A~%" line 10 42))
                   '(a abcd asdf foobar g november))
           sb)
"A         = 42
ABCD     = 42
ASDF     = 42
FOOBAR   = 42
G        = 42
NOVEMBER = 42
"
Run Code Online (Sandbox Code Playgroud)

重要的问题是"为什么?" 我在Mac上使用SBCL 1.3.1并且没有在其他实现上尝试过.它可能是一个错误,但似乎更合理的是它的预期行为,但我不明白它可能要完成什么,我无法在格式的文档中找到解释.

Sva*_*nte 4

我认为这是一个错误。我还可以使用 SBCL 1.3.1 在 Linux 上重现它。

~T在某些情况下可能需要启发式(可能会失败)来确定当前列,但我猜字符串的开头应该被视为第 0 列。

至少在我的计算机上,with-output-to-string使用简单时似乎不会发生:

(with-output-to-string (s)
  (mapcar (lambda (line)
            (format s "~A~VT= ~A~%" line 10 42))
          '(a abcd asdf foobar g november)))
Run Code Online (Sandbox Code Playgroud)

但是,当您将预制字符串提供给以下时,它确实会发生with-output-to-string

(let ((sb (make-array 0
                      :element-type 'character
                      :adjustable t
                      :fill-pointer 0)))
  (with-output-to-string (s sb)
    (mapcar (lambda (line)
              (format s "~A~VT= ~A~%" line 10 42))
            '(a abcd asdf foobar g november))
    sb))
Run Code Online (Sandbox Code Playgroud)

  • “如果失败,format 可能会在调用 format 时目标位于零列的风险更大的假设上尝试类似的推导。如果即使这种启发式失败或实现上不方便,最坏的情况下 ~T 操作只会输出两个空格。” (2认同)