LISP - 访问字符串字符
Lisp - 访问字符串中的字符
Section titled “Lisp - 访问字符串中的字符”在 Common Lisp 中,字符串是一维字符数组。这种结构允许通过索引高效、直接地访问任何字符。有几个标准函数可以执行这种访问,每个函数在使用和性能上都有细微的差异。
记住以下关键点:
- 零基索引(Zero-Based Indexing):第一个字符的索引是 0,第二个是 1,依此类推。
- 字符类型(Character Type):这些函数返回
character类型的值,Lisp 使用#\符号打印它(例如,#\A)。
核心访问函数
Section titled “核心访问函数”| 函数 | 描述 | 最佳用途 |
|---|---|---|
char | 最通用和推荐的函数。它适用于任何类型的字符串。 | 通用字符串访问。 |
schar | char 的一个特化版本,只适用于 simple-string。它可能更快,因为它避免了复杂字符串(例如,带有填充指针的字符串)所需的检查。 | 性能关键的代码,当你确定字符串是 simple-string 时使用。 |
aref | 通用数组引用函数。由于字符串是数组,因此它可以用来访问字符。为此目的,它在功能上等同于 char。 | 操作任何类型数组的通用代码,而不仅仅是字符串。 |
示例:比较 char、schar 和 aref
Section titled “示例:比较 char、schar 和 aref”以下示例演示了如何使用这三个函数从字符串中访问字符。请注意,对于标准字符串字面量,它们的行为是相同的。
main.lisp
Section titled “main.lisp”;; 使用 defparameter 定义一个全局的动态变量(一种常见约定)。(defparameter *my-string* "Modern Lisp")
(format t "Original String: ~s~%~%" *my-string*)
;; --- 访问第一个字符(索引 0) ---(format t "Using (char *my-string* 0): ~c~%" (char *my-string* 0))(format t "Using (schar *my-string* 0): ~c~%" (schar *my-string* 0))(format t "Using (aref *my-string* 0): ~c~%~%" (aref *my-string* 0))
;; --- 访问第七个字符(索引 6) ---(let ((index 6)) (format t "Accessing character at index ~d:~%" index) (format t "Character is: ~c~%" (char *my-string* index)))Original String: "Modern Lisp"
Using (char *my-string* 0): MUsing (schar *my-string* 0): MUsing (aref *my-string* 0): M
Accessing character at index 6:Character is: L常见错误和调试技巧
Section titled “常见错误和调试技巧”- 差一错误(Off-by-One Error):忘记索引从 0 开始是一个常见错误。字符串
s的最后一个字符的索引是(- (length s) 1)。 - 索引越界(Index Out of Bounds):尝试访问等于或大于字符串长度的索引将发出运行时错误信号。请务必确保你的索引在有效范围
[0, length-1]内。 schar的类型错误(Type Error withschar):如果你在一个复杂字符串(例如,使用填充指针创建的字符串)上使用schar,将会发出type-error信号。除非你有特定的性能原因并且已验证字符串类型,否则请坚持使用char。
;; 索引越界错误的示例(let ((my-string "Hi")) ;; 这将导致错误,因为有效索引是 0 和 1。 (char my-string 2))为了清晰、健壮和通用代码,优先使用 char。在现代 Lisp 实现中,schar 带来的潜在性能提升通常可以忽略不计,除非你正在对数百万个字符进行紧密循环操作。当编写旨在处理一般数组而不仅仅是字符串的代码时,请使用 aref。