Skip to content

LISP - 向量修改

在 Common Lisp 中,向量 (vector) 是一种一维数组,可以容纳任何类型的元素。向量是管理有序集合的基本且高效的数据结构。本教程涵盖了创建、访问和修改向量的现代标准方法,重点介绍了当今 Lisp 开发的最佳实践。

使用 vector、aref 和 setf 创建和修改向量

Section titled “使用 vector、aref 和 setf 创建和修改向量”

用于向量操作的最常见和通用工具是:

  • vector:一个用于创建带有指定元素的新简单向量的函数。
  • aref:数组引用 (Array REFerence) 函数,用于访问特定索引处的元素。
  • setf:通用赋值宏,与 aref 结合使用,用于修改特定索引处的元素。

尽管你可能会在旧代码中看到 svref(简单向量引用),但 aref 是更通用且推荐的函数,因为它适用于所有数组类型,包括向量。现代 Lisp 编译器经过高度优化,通常会在简单向量上为 aref 生成同样高效的代码。

(defun vector-modification-example ()
"Demonstrates creating, accessing, and modifying a vector."
;; 1. 使用 `vector` 函数创建一个向量。
;; 最佳实践是使用 `let` 创建局部变量。
(let ((my-vector (vector 'a 'b 'c 'd)))
;; 2. 打印原始向量。
;; `format` 比 `print` 更灵活。
;; ~a 用于美观输出,~s 用于 Lisp 可读输出。
(format t "Original vector: ~s~%" my-vector)
;; 3. 修改索引 1 处的元素(第二个元素)。
;; Lisp 使用零基索引。
(setf (aref my-vector 1) 'z)
;; 4. 打印更新后的向量以显示更改。
(format t "Modified vector: ~s~%" my-vector)))
;; 运行示例函数
(vector-modification-example)

当你在现代 Lisp 环境中编译并运行此代码时,你将看到:

Original vector: #(A B C D)
Modified vector: #(A Z C D)
  • 零基索引:请记住,向量的第一个元素在索引 0 处,第二个在索引 1 处,依此类推。最后一个元素在索引 (- (length vector) 1) 处。
  • 错误处理:访问向量边界外的索引(例如,4 元素向量中的索引 4)将引发 control-error。在实际应用中,你应该验证索引或使用 handler-case 处理错误。
  • 通用向量与简单向量:(vector ...) 创建一个简单向量,其大小是固定的。你也可以使用 make-array 创建带有填充指针 (fill pointer) 的可调整向量。对于大多数用例,简单向量是足够且高效的。
  • 现代开发工作流:对于严肃的 Lisp 开发,请使用现代设置,例如 SBCL(高性能编译器)、Quicklisp(包管理器)和 ASDF(构建系统)。像 Emacs 配合 SLIME/SLY 或 VS Code 配合 Alive 这样的交互式编辑器提供了强大的 REPL 驱动开发体验。

如果你不确定程序中向量的状态或类型,可以在 REPL 中使用 inspect 函数。例如,(inspect my-vector) 将打开一个交互式检查器,显示向量的类型、长度和内容,这对于调试来说是无价的。