为什么字符串不是scheme/racket中的字符列表?

Wys*_*ard 2 lisp string scheme racket

我习惯的是字符串只是一个列表或字符数组,就像大多数类C语言一样.但是,在我使用的方案实现中,包括Chicken和Racket,字符串与字符列表不同.就像是(car "mystring")只是不会飞.相反,有从列表转换的功能.为什么选择这个?在我看来,Haskell是最好的方式,在字符列表和字符串之间没有任何区别.我最喜欢这个,因为它以最清晰,最简单的方式传达字符串含义.我不完全确定,但我猜在"背景"字符串中几乎是任何语言的列表或字符数组.我特别期待一种像简化方案一样的语言以这种方式处理字符串,或者至少make是如此,你可以用字符串做你可以用列表做什么,比如拿car或者cdr我错过了什么?

Jos*_*lor 6

根据Racket文档,字符串字符数组:

4.3字符串

字符串是固定长度的字符数组.

一个阵列,如该术语在编程语言中通常使用,尤其是在C和C++,是的存储器与它支持高效重要性质的连续块的随机访问.例如,您可以像第n (x [n-1])一样快地访问第一个元素(x [0 ]).链接列表(默认情况下在Lisps中遇到的列表)支持高效的随机访问.

因此,由于字符串是Racket中的数组,因此您希望x [i]表示法有一些对应部分(不是很Lispy).在Racket中,你使用string-refstring-set!,在同一页面上记录.例如:

(string-ref "mystring" 1) ;=> #\y 
Run Code Online (Sandbox Code Playgroud)

(现在,还有vector-refvector-set!程序用于更广义的向量.在一些Lisps中,字符串也是向量,所以你可以在字符串上使用通用向量和数组操作函数.我不是一个Racket用户,所以我不确定这是否适用于Racket.)


Ale*_*uth 6

看起来你真正要问的是,为什么不存在适用于字符串和列表的泛型操作?

那些确实存在于像通用集合库这样的库中.

#lang racket/base
(require data/collection)
(first '(my list)) ; 'my
(first "mystring") ; #\m
Run Code Online (Sandbox Code Playgroud)

此外,map来自此库的操作可以与多个不同类型的集合一起使用.

#lang racket/base
(require data/collection)
(define (digit->char n)
  (first (string->immutable-string (number->string n))))
(first (map string (map digit->char '(1 2 3)) "abc"))
; "1a"
Run Code Online (Sandbox Code Playgroud)

这并不意味着字符串是列表,但它确实意味着字符串和列表都是序列,序列上的操作可以同时处理两种数据类型.


Seg*_*ult 5

从技术上讲,“数组”通常是一块连续的内存,而“列表”通常被理解为独立分配的对象的单链表或双链表。在大多数常见的编程语言中,包括 C 以及我所知道的所有 Lisp 和 Scheme 方言,出于性能原因,字符串数据存储在数组中,即存储在连续的内存中。

令人困惑的是,有时它们可​​能仍然通俗地称为列表,当将“列表”理解为精确的技术术语“链接列表”时,这是不正确的。

如果一个字符串真正存储为列表,包括Scheme 和 Lisp 通常如何存储一个字符串,那么每个字符都会产生成为包含该字符和至少一个指针(指向下一个字符)的对象的一部分的开销。