LISP - 使用 `Format` 格式化
Lisp format 函数实用指南
Section titled “Lisp format 函数实用指南”Common Lisp 中的 format 函数是文本格式化和输出的独特强大工具。它作用如同 Lisp 中的一种微型语言,能够精确控制文本呈现,生成简单或复杂的字符串。它远比简单的字符串连接或在其他语言中找到的 printf 功能强大。
(format destination control-string &rest arguments)destination:输出目标。常见的值有t(标准输出,即控制台)、nil(将格式化文本作为新字符串返回)或一个流。control-string:包含纯文本和特殊格式指令的字符串。每个指令都以波浪号(~)开头。arguments:要格式化的值,每个需要参数的指令对应一个。
常用格式指令
Section titled “常用格式指令”以下是最重要的指令细分,按类别分组。
1. 基本和通用指令
Section titled “1. 基本和通用指令”~A(Aesthetic):以人类可读的格式打印一个参数。适用于大多数通用目的。(format nil "Hello, ~A!" "World")->"Hello, World!"~S(S-Expression):以 Lisp 可读的格式(S-表达式)打印一个参数,字符串和符号会带引号。(format nil "The value is ~S." "a string")->"The value is \"a string\"."~%(Newline):插入一个换行符。~~(Tilde):插入一个字面量的波浪号字符。
2. 数字格式化指令
Section titled “2. 数字格式化指令”~D(Decimal):以十进制打印一个整数。~B(Binary):以二进制打印一个整数。~X(Hexadecimal):以十六进制(大写)打印一个整数。~F(Floating-point):打印一个浮点数。可以接受宽度和精度的参数。~R(Radix):以 2 到 36 之间的任何进制打印一个整数,或以英文单词形式打印(例如,(format nil "~R" 27)->"twenty-seven")。
示例 1:格式化为字符串
Section titled “示例 1:格式化为字符串”将 nil 用作目标非常适合以编程方式构建字符串。
(let ((user "Alice") (items 5)) (let ((message (format nil "User ~S has ~D item(s) in their cart." user items))) (print message)))"User \"Alice\" has 5 item(s) in their cart."示例 2:填充和对齐
Section titled “示例 2:填充和对齐”指令可以接受前缀参数(mincol、padchar)来控制对齐和填充。格式为 ~<mincol>,<padchar><directive>。
;; 将数字 5 打印为二进制字符串,用 '0' 填充至最小宽度 8。(format t "~8,'0B~%" 5)
;; 将字符串右对齐打印在一个 10 个字符宽的列中。(format t "|~10A|~%" "test")00000101| test|现代用例和最佳实践
Section titled “现代用例和最佳实践”- Structured Logging:
format非常适合创建详细、格式良好的日志消息。您可以轻松地包含时间戳、严重性级别和结构化数据。 - Generating Reports:使用它来生成简单的文本报告、CSV 文件或其他基于行的传输格式。
- Readability:对于复杂的格式化,特别是包含条件逻辑(
~[)或迭代(~{)时,format字符串可能变得难以阅读。考虑将复杂逻辑分解为辅助函数,并保持控制字符串相对简单。 - Security Note:当将用户输入合并到
format字符串中时,务必将其作为指令的参数(例如~A)传递。切勿从不受信任的输入构造control-string本身,因为这可能导致安全漏洞(格式字符串攻击)。
本教程仅仅触及了皮毛。Common Lisp Hyperspec 中关于 format 的条目是权威参考。探索高级指令,如用于列表迭代的 ~{...~} 和用于条件格式化的 ~[...~],以发挥其全部潜力。