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