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

时间:2016-01-21 15:24:30

标签: string scheme lisp racket

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

3 个答案:

答案 0 :(得分:6)

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

  

4.3 Strings

     

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

一个数组,因为这个术语通常用在编程语言中,特别是在C和C ++中,是一个连续的内存块,它具有支持高效随机的重要属性访问。例如,您可以像n th (x [n-1])一样快地访问第一个元素(x [0])。链接列表,默认情况下在Lisps中遇到的列表, don 支持有效的随机访问。

所以,因为字符串是Racket中的数组,所以你希望x [i]表示法有一些对应物(它不是很好的)。在Racket中,您使用 string-ref string-set!,这些内容记录在同一页面上。 E.g:

(string-ref "mystring" 1) ;=> #\y 

(现在,对于更广义的向量,还有 vector-ref 向量集!过程。在一些Lisps中,字符串也是向量,所以你可以使用字符串上的一般向量和数组操作函数。我不是一个Racket用户,所以我不确定它是否也适用于Racket。)

答案 1 :(得分:6)

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

generic collections库这样的库中确实存在。

#lang racket/base
(require data/collection)
(first '(my list)) ; 'my
(first "mystring") ; #\m

此外,此库中的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"

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

答案 2 :(得分:4)

技术上"阵列"通常是一段连续的记忆,而#34; list"通常被理解为独立分配的对象的单链或双链表。在大多数常见的编程语言中,包括C,以及我所知道的所有Lisp和Scheme方言,出于性能原因,字符串数据存储在一个数组中,因为它存储在连续的内存中。

令人困惑的是,有时它们可​​能仍然被俗称为列表,这在理解" list"时是不正确的。作为精确的技术术语"链表"。

如果一个字符串真正存储为列表,包括Scheme和Lisp通常如何存储一个字符串,那么每个字符都会成为包含该字符的对象的一部分,并且至少有一个指针,即下一个字符。 / p>