向量(vector)
可以说是一个非常好用的类型 ,是一种元素按整数来索引的对象,异源的数据结构,在占用空间上比同样元素的列表要少,在外观上:
列表示为: (1 2 3 4)
VECTOR表示为: #(1 2 3 4)
可以正常定义:(define v (vector 3 4 5))
也可以直接定义:(define v #(3 4 5))
vector是一种比较常用的复合类型,它的元素索引从0开始,至第 n-1 结束,这一点有点类似C语言中的数组。
关于向量表(vector)的常用操作过程:
1
2
3
4
5
6
7
8
9
10
11
12
13
| guile> (define v (vector 1 2 3 4 5))
guile> v
#(1 2 3 4 5)
guile> (vector-ref v 0) ; 求第n个变量的值
1
guile> (vector-length v) ; 求vector的长度
5
guile> (vector-set! v 2 "abc") ; 设定vector第n个元素的值
guile> v
#(1 2 "abc" 4 5)
guile> (define x (make-vector 5 6)) ; 创建向量表
guile> x
#(6 6 6 6 6)
|
make-vector用来创建一个向量表,第一个参数是数量,后一个参数是添充的值,这和列表中的make-list非常相似。
我们可以看出,在Scheme语言中,每种数据类型都有一些基本的和它相关的操作过程,如字符串,列表等相关的操作,这些操作过程都很有规律,过程名的单词之间都用-号隔开,很容易理解。对于学过C++的朋友来说,更类似于某个对象的方法,只不过表现的形式不同了。
3. 类型的判断、比较、运算、转换与方法类型判断
Scheme语言中所有判断都是用类型名加问号再加相应的常量或变量构成,形如:
Scheme语言在类型定义中有比较严格的界定,如在C语言等一些语言中数字0来代替逻辑类型数据False,在Scheme语言中是不允许的。
以下为常见的类型判断和附加说明:
逻辑型:
1
2
3
| (boolean? #t) => #t
(boolean? #f) => #t 因为#t和#f都是boolean类型,所以其值为#t
(boolean? 2) => #f 因为2是数字类型,所以其值为 #f
|
字符型
1
2
3
4
5
6
| (char? #\space) => #t
(char? #\newline) => #t 以上两个特殊字符:空格和换行
(char? #\f) => #t 小写字母 f
(char? #\;) => #t 分号 ;
(char? #\5) => #t 字符 5 ,以上这些都是正确的,所以返回值都是 #t
(char? 5) => #f 这是数字 5 ,不是字符类型,所以返回 #f
|
数字型
1
2
3
4
5
6
7
8
9
10
11
12
13
| (integer? 1) => #t
(integer? 2345) => #t
(integer? -90) => #t 以上三个数均为整数
(integer? 8.9) => #f 8.9不整数
(rational? 22/7) => #t
(rational? 2.3) => #t
(real? 1.2) => #t
(real? 3.14159) => #t
(real? -198.34) => #t 以上三个数均为实数型
(real? 23) => #t 因为整型属于实型
(number? 5) => #t
(number? 2.345) => #t
(number? 22/7) => #t
|
其它型
1
2
3
4
5
| (null? '()) => #t ; null意为空类型,它表示为 '() ,即括号里什么都没有的符号
(null? 5) => #f
(define x 123) 定义变量x其值为123
(symbol? x) => #f
(symbol? 'x) => #t ; 此时 'x 为符号x,并不表示变量x的值
|
在Scheme语言中如此众多的类型判断功能,使得Scheme语言有着非常好的自省功能。即在判断过程的参数是否附合过程的要求。
比较运算
Scheme语言中可以用<,>,<=,>=,= 来判断数字类型值或表达式的关系,如判断变量x是否等于零,它的形式是这样的:(= x 0) ,如x的值为0则表达式的值为#t,否则为#f。
还有下面的操作:
1
2
| (eqv? 34 34) => #t
(= 34 34) => #t
|
以上两个form功能相同,说明 eqv? 也可以用于数字的判断。
在Scheme语言中有三种相等的定义,两个变量正好是同一个对象;两个对象具有相同的值;两个对象具有相同的结构并且结构中的内容相同。除了上面提到的符号判断过程和eqv?外,还有eq?和equal?也是判断是否相等的过程。
eq?,eqv?,equal?
eq?,eqv?和equal?是三个判断两个参数是否相等的过程,其中eq?和eqv?的功能基本是相同的,只在不同的Scheme语言中表现不一样。
eq?是判断两个参数是否指向同一个对象,如果是才返回#t;equal?则是判断两个对象是否具有相同的结构并且结构中的内容是否相同,它用eq?来比较结构中成员的数量;equal?多用来判断点对,列表,向量表,字符串等复合结构数据类型。
1
2
3
4
5
6
| guile> (define v (vector 3 4 5))
guile> (define w #(3 4 5)) ; w和v都是vector类型,具有相同的值#(3 4 5)
guile> (eq? v w)
#f ; 此时w和v是两个对象
guile> (equal? v w)
#t ; 符合equal?的判断要求
|
以上操作说明了eq? 和equal? 的不同之处,下面的操作更是证明了这一点:
1
2
3
4
5
6
7
8
9
10
11
12
| guile> (define x (make-vector 5 6))
guile> x
#(6 6 6 6 6)
guile> (eq? x x) ; 是同一个对象,所以返回#t
#t
guile> (define z (make-vector 5 6))
guile> z
#(6 6 6 6 6)
guile> (eq? x z) ; 不是同一个对象
#f
guile> (equal? x z) ; 结构相同,内容相同,所以返回#t
#t
|
算术运算
Scheme语言中的运算符有:
+ , - , * , / 和 expt (指数运算)
其中 - 和 / 还可以用于单目运算,如:
1
2
| (- 4) => -4
(/ 4) => 1/4
|
此外还有许多扩展的库提供了很多有用的过程,
1
2
3
| max 求最大 (max 8 89 90 213) => 213
min 求最小 (min 3 4 5 6 7) => 3
abs 求绝对值 (abs -7) ==> 7
|
除了max,min,abs外,还有很多数学运算过程,这要根据你用的Scheme语言的运行环境有关,不过它们大多是相同的。在R5RS中规定了很多运算过程,在R5RS的参考资料中可以很容易找到。
转换
Scheme语言中用符号组合"->"来标明类型间的转换(很象C语言中的指针)的过程,就象用问号来标明类型判断过程一样。下面是一些常见的类型转换过程:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
| guile> (number->string 123) ; 数字转换为字符串
"123"
guile> (string->number "456") ; 字符串转换为数字
456
guile> (char->integer #\a) ;字符转换为整型数,小写字母a的ASCII码值为96
97
guile> (char->integer #\A) ;大写字母A的值为65
65
guile> (integer->char 97) ;整型数转换为字符
#\a
guile> (string->list "hello") ;字符串转换为列表
(#\h #\e #\l #\l #\o)
guile> (list->string (make-list 4 #\a)) ; 列表转换为字符串
"aaaa"
guile> (string->symbol "good") ;字符串转换为符号类型
good
guile> (symbol->string 'better) ;符号类型转换为字符串
"better"
|
|