LISP - 访问向量元素
Lisp - 访问向量元素
Section titled “Lisp - 访问向量元素”在 Common Lisp 中,**向量(vector)**是一种一维数组。作为一种基本数据结构,了解如何高效地访问其元素是一项核心技能。本教程将介绍现代、惯用的向量元素检索方法。
通用访问器:aref
Section titled “通用访问器:aref”aref 函数(array reference 的缩写,即“数组引用”)是用于访问包括向量在内的任何数组元素的标准通用函数。它是现代 Lisp 代码中访问向量元素最常用和推荐的方式。
main.lisp
Section titled “main.lisp”;; 为了简单起见,使用 'vector' 构造器定义一个向量。(let ((my-vector (vector 10 20 30 40 50)))
;; 访问并打印第一个元素(索引为 0)。 ;; Lisp 向量与大多数编程语言中的数组一样,是零索引的。 (format t "First element: ~a~%" (aref my-vector 0))
;; 访问并打印第四个元素(索引为 3)。 (format t "Fourth element: ~a~%" (aref my-vector 3)))First element: 10Fourth element: 40专用于性能优化的访问器
Section titled “专用于性能优化的访问器”虽然 aref 是通用的,但 Common Lisp 为特定的向量类型提供了专用函数,这些函数在编译后的代码中可以提供更好的性能。
针对简单向量:svref
Section titled “针对简单向量:svref”**简单向量(simple vector)**是一种未移位(not displaced)、无填充指针(no fill pointer)且不可调整(not adjustable)的向量。如果您确定正在使用简单向量(这通常是情况),那么 svref(simple vector reference,即“简单向量引用”)会比 aref 更高效,因为编译器无需检查这些特殊特性。
main.lisp
Section titled “main.lisp”;; (vector ...) 构造器创建的是一个简单向量。(let ((simple-vec (vector "apple" "banana" "cherry")))
;; 在这里使用 svref 是高效的。 (format t "Element at index 2: ~s~%" (svref simple-vec 2)))Element at index 2: "cherry"通用序列访问器:elt
Section titled “通用序列访问器:elt”elt 函数是任何**序列(sequence)**类型的通用访问器,这包括列表、向量和字符串。您可以在向量上使用 elt,它的行为与 aref 完全相同。它的主要优点是能够编写对不同类型序列进行操作而无需修改代码的函数。
main.lisp
Section titled “main.lisp”;; 一个获取任何序列中第二个元素的函数。(defun get-second-element (sequence) (when (>= (length sequence) 2) (elt sequence 1)))
(let ((my-vector #(100 200 300)) (my-list '(a b c)))
(format t "Second element of vector: ~a~%" (get-second-element my-vector)) (format t "Second element of list: ~a~%" (get-second-element my-list)))Second element of vector: 200Second element of list: B最佳实践与常见错误
Section titled “最佳实践与常见错误”- 默认使用
aref:对于通用向量访问,aref是明确的选择。它可读性好,对所有数组通用,并且现代 Lisp 编译器在优化它方面表现出色。 - 使用
svref进行优化:仅当您处于代码的性能关键部分并且已经通过性能分析得知数组访问是瓶颈时,才切换到svref。 - 使用
elt提升泛用性:当编写需要对不同序列类型多态操作的函数时,使用elt。 - 错误:越界索引:访问负数索引或大于等于向量长度的索引会引发错误。请始终确保您的索引在有效范围
[0, (length vector) - 1]内。 - 调试技巧:如果您遇到意外的越界错误,请在
aref调用之前使用(format t "Accessing vector ~s at index ~d~%" my-vector index)来检查导致问题的数值。