Racket编程指南——3 内置的数据类型
2018-02-17 10:43
501 查看
3 内置的数据类型
上一章介绍了Racket的内置数据类型:数字、布尔值、字符串、列表、和程序。本节提供了简单的数据表的内置数据表更完整的覆盖。3.1 布尔值(Boolean) |
3.2 数值(Number) |
3.3 字符(Character) |
3.4 字符串(Unicode Strings) |
3.5 字节(Byte)和字节字符串(Byte String) |
3.6 符号(Symbol) |
3.7 关键字(Keyword) |
3.8 配对(Pair)和列表(List) |
3.9 向量(Vector) |
3.10 哈希表(Hash Table) |
3.11 格子(Box) |
3.12 空值(Void)和未定义值(Undefined) |
3.1 布尔值(Boolean)
Racket有表示布尔值的两个常数:#t表示真,#f表示假。大写的#T和#F在语法上描述为同样的值,但小写形式是首选。boolean?过程识别两个布尔常量。然而,在对if、cond、 and、or等等的测试表达式的结果里,除了#f外,任何值都是记为真。
Examples:
> (= 2 (+ 1 1)) |
#t |
> (boolean? #t) |
#t |
> (boolean? #f) |
#t |
> (boolean? "no") |
#f |
> (if "no" 1 0) |
1 |
3.2 数值(Number)
Racket的数值(number)可以是精确的也可以是不精确的:一个精确的数字是:
一个任意大的或小的整数,比如:5,99999999999999999或-17;
一个有理数,即精确的两个任意小的或大的整数比,比如:1/2,99999999999999999/2或-3/4;
一个复数,带有精确的实部和虚部(即虚部不为零),比如:1+2i或1/2+3/4i。
一个 不精确的数字是:
一个数的一个IEEE浮点表示,比如:2.0或3.14e+87,其中IEEE无穷大和非数书写为:+inf.0,-inf.0和+nan.0(或-nan.0);
一个带有实部和虚部配对的复数的IEEE浮点表示,比如:2.0+3.0i或-inf.0+nan.0i;一种特殊情况是,一个不精确的复数可以有一个精确的零实部和一个不精确的虚部。
对一个小数点或指数的说明符进行不精确数字打印,对整数和分数进行精确数字打印。用同样的约定申请读入数值常数,但#e或#i可以前缀数值以解析一个精确的或不精确的数值。前缀#b、#o和#x指定二进制、八进制和十六进制数值的解释。
Examples:
> 0.5 |
0.5 |
> #e0.5 |
1/2 |
> #x03BB |
955 |
Examples:
> (/ 1 2) |
1/2 |
> (/ 1 2.0) |
0.5 |
> (if (= 3.0 2.999) 1 2) |
2 |
> (inexact->exact 0.1) |
3602879701896397/36028797018963968 |
Examples:
| ||
0 | ||
| ||
0.479425538604203 |
| ||||||
|
Examples:
> (integer? 5) |
#t |
> (complex? 5) |
#t |
> (integer? 5.0) |
#t |
> (integer? 1+2i) |
#f |
> (complex? 1+2i) |
#t |
> (complex? 1.0+2.0i) |
#t |
> (abs -5) |
5 |
> (abs -5+2i) |
abs: contract violation |
expected: real? |
given: -5+2i |
> (sin -5+2i) |
3.6076607742131563+1.0288031496599335i |
Examples:
> (= 1 1.0) |
#t |
> (eqv? 1 1.0) |
#f |
Examples:
> (= 1/2 0.5) |
#t |
> (= 1/10 0.1) |
#f |
> (inexact->exact 0.1) |
3602879701896397/36028797018963968 |
3.3 字符(Character)
Racket 字符(character)对应于Unicode标量值(scalarvalue)。粗略地说,一个标量值是一个无符号整数,它的表示适合21位,并且映射到某种自然语言字符或字符块的某些概念。从技术上讲,标量值是比Unicode标准中的“字符”概念更简单的概念,但它是一种用于许多目的的近似值。例如,任何重音罗马字母都可以表示为一个标量值,就像任何普通的汉字一样。
虽然每个Racket字符对应一个整数,但字符数据类型和数值是有区别的。char->integer和integer->char程序在标量值和相应字符之间转换。
一个可打印字符通常在以#\作为代表字符后打印。一个不可打印字符通常在以#\u开始十六进制数的标量值打印。几个字符特殊打印;例如,空格和换行字符分别打印为#\space和#\newline。
Examples:
> (integer->char 65) |
#\A |
> (char->integer #\A) |
65 |
> #\λ |
#\λ |
> #\u03BB |
#\λ |
> (integer->char 17) |
#\u0011 |
> (char->integer #\space) |
32 |
Input and Output),与用于打印字符结果的字符常量语法形成对照。
Examples:
> #\A |
#\A |
> (display #\A) |
A |
Examples:
> (char-alphabetic? #\A) |
#t |
> (char-numeric? #\0) |
#t |
> (char-whitespace? #\newline) |
#t |
> (char-downcase #\A) |
#\a |
> (char-upcase #\ß) |
#\ß |
Examples:
> (char=? #\a #\A) |
#f |
> (char-ci=? #\a #\A) |
#t |
> (eqv? #\a #\A) |
#f |
3.4 字符串(Unicode Strings)
字符串(string)是固定长度的字符(characters)数组。它使用双引号打印,双引号和反斜杠字符在字符串中是用反斜杠转义。其他常见的字符串转义是支持的,包括\n换行, \r回车,使用\后边跟随三个八进制数字实现八进制转义,使用\u(达四位数)实现十六进制转义。在打印字符串时通常用\u显示字符串中的不可打印字符。display过程直接将字符串的字符写入当前输出端口(见《输入和输出》)( 输入和输出),与打印字符串结果的字符串常量语法形成对照。
Examples:
> "Apple" | ||
"Apple" | ||
> "\u03BB" | ||
"λ" | ||
> (display "Apple") | ||
Apple | ||
> (display "a \"quoted\" thing") | ||
a "quoted" thing | ||
> (display "two\nlines") | ||
| ||
> (display "\u03BB") | ||
λ |
Examples:
> (string-ref "Apple" 0) |
#\A |
> (define s (make-string 5 #\.)) |
> s |
"....." |
> (string-set! s 2 #\λ) |
> s |
"..λ.." |
Examples:
> (string<? "apple" "Banana") | ||
#f | ||
> (string-ci<? "apple" "Banana") | ||
#t | ||
> (string-upcase "Straße") | ||
"STRASSE" | ||
| ||
"STRAßE" |
3.5 字节(Byte)和字节字符串(Byte String)
字节(byte)是包含0到255之间的精确整数。byte?判断表示字节的数字。Examples:
> (byte? 0) |
#t |
> (byte? 256) |
#f |
string)类似于字符串——参见《字符串(Unicode)》(字符串(Unicode Strings))部分,但它的内容是字节序列而不是字符。字节字符串可用于处理纯ASCII而不是Unicode文本的应用程序中。一个字节的字符串打印形式特别支持这样的用途,因为一个字节的字符串打印的ASCII的字节字符串解码,但有一个#前缀。在字节字符串不可打印的ASCII字符或非ASCII字节用八进制表示法。
Examples:
> #"Apple" |
#"Apple" |
> (bytes-ref #"Apple" 0) |
65 |
> (make-bytes 3 65) |
#"AAA" |
> (define b (make-bytes 2 0)) |
> b |
#"\0\0" |
> (bytes-set! b 0 1) |
> (bytes-set! b 1 255) |
> b |
#"\1\377" |
Examples:
> (display #"Apple") |
Apple |
> (display "\316\273") ; same as "λ" |
λ |
> (display #"\316\273") ; UTF-8 encoding of λ |
λ |
Examples:
> (bytes->string/utf-8 #"\316\273") | ||||||
"λ" | ||||||
> (bytes->string/latin-1 #"\316\273") | ||||||
"λ" | ||||||
| ||||||
bytes->string/locale: byte string is not a valid encoding | ||||||
for the current locale | ||||||
byte string: #"\316\273" | ||||||
| ||||||
"λ" |
3.6 符号(Symbol)
符号(symbol)是一个原子值,它像前面的标识符那样以'前缀打印。一个表达式以'开始并以标识符继续表达式产生一个符号值。Examples:
> 'a |
'a |
> (symbol? 'a) |
#t |
符号是区分大小写的。通过使用一个#ci前缀或其它方式,在读者保留默认情况下,读者可以将大小写字符序列生成一个符号。
Examples:
> (eq? 'a 'a) |
#t |
> (eq? 'a (string->symbol "a")) |
#t |
> (eq? 'a 'b) |
#f |
> (eq? 'a 'A) |
#f |
> #ci'A |
'a |
( ) [ ] { } " , ' ` ; # | \
实际上,#只有在一个符号开始是不允许的,或者仅仅如果随后是%;然而,#也被允许。同样。.它本身不是一个符号。
空格或特殊字符可以通过用|或\引用包含标识符。这些引用机制用于包含特殊字符或可能看起来像数字的标识符的打印形式中。
Examples:
> (string->symbol "one, two") |
'|one, two| |
> (string->symbol "6") |
'|6| |
Examples:
> (write 'Apple) |
Apple |
> (display 'Apple) |
Apple |
> (write '|6|) |
|6| 20000 |
> (display '|6|) |
6 |
Examples:
> (define s (gensym)) |
> s |
'g42 |
> (eq? s 'g42) |
#f |
> (eq? 'a (string->uninterned-symbol "a")) |
#f |
3.7 关键字(Keyword)
一个关键字(keyword)值类似于一个符号(见《符号(Symbols)》(符号(Symbol))),但它的打印形式是用前缀#:。Examples:
> (string->keyword "apple") |
'#:apple |
> '#:apple |
'#:apple |
> (eq? '#:apple (string->keyword "apple")) |
#t |
Examples:
> not-a-symbol-expression |
not-a-symbol-expression: undefined; |
cannot reference undefined identifier |
> #:not-a-keyword-expression |
eval:2:0: #%datum: keyword used as an expression |
in: #:not-a-keyword-expression |
Examples:
> (define dir (find-system-path 'temp-dir)) ; not '#:temp-dir | ||||||
|
3.8 配对(Pair)和列表(List)
一个配对(pair)把两个任意值结合。cons过程构建配对,car和cdr过程分别提取配对的第一和第二个成员。pair?判断确认配对。一些配对通过圆括号包围两个配对元素的打印表来打印,在开始位置放置',在元素之间放置.。
Examples:
> (cons 1 2) |
'(1 . 2) |
> (cons (cons 1 2) 3) |
'((1 . 2) . 3) |
> (car (cons 1 2)) |
1 |
> (cdr (cons 1 2)) |
2 |
> (pair? (cons 1 2)) |
#t |
一个列表通常打印为一个'后跟一对括号括在列表元素周围。
Examples:
> null |
'() |
> (cons 0 (cons 1 (cons 2 null))) |
'(0 1 2) |
> (list? null) |
#t |
> (list? (cons 1 (cons 2 null))) |
#t |
> (list? (cons 1 2)) |
#f |
> (srcloc "file.rkt" 1 0 1 (+ 4 4)) |
(srcloc "file.rkt" 1 0 1 8) |
> (list 'here (srcloc "file.rkt" 1 0 1 8) 'there) |
(list 'here (srcloc "file.rkt" 1 0 1 8) 'there) |
> (cons 1 (srcloc "file.rkt" 1 0 1 8)) |
(cons 1 (srcloc "file.rkt" 1 0 1 8)) |
> (cons 1 (cons 2 (srcloc "file.rkt" 1 0 1 8))) |
(list* 1 2 (srcloc "file.rkt" 1 0 1 8)) |
write和display函数不带前导'、cons、list或list*打印一个配对或一个列表。一个配对或列表的write和display没有区别,除非它们运用于列表元素:
Examples:
> (write (cons 1 2)) |
(1 . 2) |
> (display (cons 1 2)) |
(1 . 2) |
> (write null) |
() |
> (display null) |
() |
> (write (list 1 2 "3")) |
(1 2 "3") |
> (display (list 1 2 "3")) |
(1 2 3) |
| |||
'(1 1/2 1/3) | |||
| |||
#f | |||
| |||
#t | |||
| |||
'(1 2) | |||
| |||
16 | |||
| |||
123 | |||
| |||
'("Keys" "U.S.A.") | |||
| |||
'(where "Florida") |
Examples:
> (define p (mcons 1 2)) |
> p |
(mcons 1 2) |
> (pair? p) |
#f |
> (mpair? p) |
#t |
> (set-mcar! p 0) |
> p |
(mcons 0 2) |
> (write p) |
{0 . 2} |
3.9 向量(Vector)
一个向量(vector)是任意值的固定长度数组。与列表不同,向量支持常量时间访问和元素更新。向量打印类似列表——作为其元素的括号序列——但向量要在'之后加前缀#,或如果某个元素不能用引号则使用vector表示。
向量作为表达式,可以提供可选长度。同时,一个向量作为一个隐式quote(引用)的表表达的内容,这意味着在一个矢量常数标识符和括号表表示的符号和列表。
Examples:
> #("a" "b" "c") |
'#("a" "b" "c") |
> #(name (that tune)) |
'#(name (that tune)) |
> #4(baldwin bruce) |
'#(baldwin bruce bruce bruce) |
> (vector-ref #("a" "b" "c") 1) |
"b" |
> (vector-ref #(name (that tune)) 1) |
'(that tune) |
向量可以通过vector->list和list->vector转换成列表,反之亦然。这种转换与列表中预定义的程序相结合特别有用。当分配额外的列表似乎太昂贵时,考虑使用像for/fold的循环形式,它像列表一样识别向量。
Example:
| ||
'#("Three" "Blind" "Mice") |
3.10 哈希表(Hash Table)
一个哈希表(hash table)实现了从键到值的映射,其中键和值可以是任意的Racket值,而对表的访问和更新通常是常量时间操作。键的比较用equal?、eqv?或eq?,取决于哈希表的键创建方式为make-hash、make-hasheqv或make-hasheq。Examples:
> (define ht (make-hash)) |
> (hash-set! ht "apple" '(red round)) |
> (hash-set! ht "banana" '(yellow long)) |
> (hash-ref ht "apple") |
'(red round) |
> (hash-ref ht "coconut") |
hash-ref: no value found for key |
key: "coconut" |
> (hash-ref ht "coconut" "not there") |
"not there" |
Examples:
> (define ht (hash "apple" 'red "banana" 'yellow)) |
> (hash-ref ht "apple") |
'red |
> (define ht2 (hash-set ht "coconut" 'brown)) |
> (hash-ref ht "coconut") |
hash-ref: no value found for key |
key: "coconut" |
> (hash-ref ht2 "coconut") |
'brown |
Examples:
| ||
> (hash-ref ht "apple") | ||
'red |
Examples:
| ||
'#hash(("apple" . red) ("banana" . yellow)) | ||
> (hash 1 (srcloc "file.rkt" 1 0 1 (+ 4 4))) | ||
(hash 1 (srcloc "file.rkt" 1 0 1 8)) |
Examples:
> (define ht (make-weak-hasheq)) |
> (hash-set! ht (gensym) "can you see me?") |
> (collect-garbage) |
> (hash-count ht) |
0 |
Examples:
> (define ht (make-weak-hasheq)) | ||
| ||
> (collect-garbage) | ||
> (hash-count ht) | ||
1 |
> (define ht (make-weak-hasheq)) | ||
| ||
> (collect-garbage) | ||
> (hash-count ht) | ||
0 |
3.11 格子(Box)
一个 格子(box)是一个单元素向量。它可以打印成一个引用#&后边跟随这个格子值的打印表。一个#&表也可以用来作为一种表达,但由于作为结果的格子是常量,它实际上没有使用。Examples:
> (define b (box "apple")) |
> b |
'#&"apple" |
> (unbox b) |
"apple" |
> (set-box! b '(banana boat)) |
> b |
'#&(banana boat) |
3.12 空值(Void)和未定义值(Undefined)
某些过程或表达式形式不需要结果值。例如,display程序仅调用输出的副作用。在这样的情况下,得到的值通常是一个特殊的常量,打印为#<void>。当一个表达式的结果是简单的#<void>,REPL不打印任何东西。void程序接受任意数量的参数并返回#<void>。(即,void标识符绑定到一个返回#<void>的过程,而不是直接绑定到#<void>。)
Examples:
> (void) |
> (void 1 2 3) |
> (list (void)) |
'(#<void>) |
| |||
|
相关文章推荐
- Racket编程指南——5 自定义的数据类型
- C# 编程指南(3):语言部分:数据类型
- hive编程指南之数据类型
- [置顶] Hive编程指南-数据类型、DDL、DML、常用字符串函数
- 编程之基础:数据类型(一)
- Windows编程数据类型概述 C++
- Python基础学习----数据类型,字符串,内置数据结构
- Python处理Excel(三):内置数据类型处理Excel数据
- Vulkan编程指南翻译 第四章 队列和命令 第5节 复制压缩图像数据
- C#编程向SQLite数据库中正确写入DateTime类型数据
- 编程杂谈---vb,vb.net,java数据类型区分
- OpenGL基础图形编程 - OpenGL数据类型和函数名
- ActiveDAQ控件的VC编程 数据采集 VARIANT数据类型的使用
- Linux 学习数据专题【管理、编程、源码分析】——Linux相关图书选购指南
- Javascript学习指南(第2版)笔记(一) Script、数据类型和变量、操作符和语句
- Python基础语法之内置的数据类型list和tuple
- Web 服务编程技巧及窍门: 改善 J2EE 与 .NET 之间的互操作性——管理集合、数组,乃至原始数据类型 (转)
- C#编程(四十一)----------用户定义的数据类型转换
- 16位或32位或64位编程各数据类型占的字节数
- c++内置数据类型的取值范围和大小总结