-
Notifications
You must be signed in to change notification settings - Fork 1
/
Red-Getting-Started.html
1066 lines (1029 loc) · 51.4 KB
/
Red-Getting-Started.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"><!-- saved from url=(0048)./Red-Getting-Started.html --><html><style id="Force_Custom_Fonts" type="text/css">@font-face{font-style:normal;font-family:"Noto Sans CJK SC Regular";src:local("Noto Sans CJK SC Regular")}@font-face{font-style:bolder;font-family:"Noto Sans CJK SC Regular";src:local("Noto Sans CJK SC Regular")}:not(pre):not(code):not(textarea):not(tt):not(kbd):not(samp):not(var){font-family:"Noto Sans CJK SC Regular"!important}pre,code,textarea,tt,kbd,samp,var{font-family:"Noto Sans Mono CJK SC Regular"!important}pre *,code *,textarea *,tt *,kbd *,samp *,var *{font-family:"Noto Sans Mono CJK SC Regular"!important}</style><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"><title>开始起步 </title>
<meta http-equiv="Page-Enter" content="RevealTrans( Duration=2,Transition=14)">
<style type="text/css">
a:hover { color: blue; text-decoration: underline; background: #F9EDED }
</style>
<style>#BAIDU_DSPUI_FLOWBAR,.adsbygoogle,.ad,div[class^="ad-widsget"],div[id^="div-gpt-ad-"],a[href*="@"][href*=".exe"],a[href*="/?/"][href*=".exe"],.adpushwin{display:none!important;max-width:0!important;max-height:0!important;overflow:hidden!important;}</style><script type="text/javascript" src="chrome-extension://ggfnopabjhlbcmchfajkadagogmohglj/js/page.js"></script><script charset="utf-8" src="chrome-extension://jgphnjokjhjlcnnajmfjlacjnjkhleah/js/btype.js"></script></head>
<body bgcolor="#000000">
<table align="center" background="./Red-Getting-Started.html" border="0" cellpadding="2" cellspacing="2" height="100%" width="95%">
<tbody>
<tr>
<td background="./Red-Getting-Started.html" bgcolor="lightgrey" valign="top">
<table background="./Red-Getting-Started.html" border="0" cellpadding="2" cellspacing="2" height="100%" width="100%">
<tbody>
<tr><td background="./Red-Getting-Started.html" bgcolor="black" height="10"><p align="center">
<a href="./index.html"><img align="baseline" alt="HEADER IMAGE" border="0" hspace="0" src="./Getting Started_files/header.png"></a>
</p></td></tr>
<tr>
<td background="./Red-Getting-Started.html" valign="top">
<table background="./Red-Getting-Started.html" bgcolor="#ffffff" border="0" cellpadding="2" cellspacing="2" height="100%" width="100%">
<tbody>
<tr>
<td background="./Red-Getting-Started.html" bgcolor="lightgrey" height="20"><center></center></td>
<td background="./Red-Getting-Started.html" bgcolor="lightgrey" height="10" width="90%"><center><a href="./Home.html">主页</a> :开始起步</center></td>
<td background="./Red-Getting-Started.html" bgcolor="lightgrey" height="20"><center></center></td>
</tr>
<tr>
<td background="./Red-Getting-Started.html" colspan="3" height="100%">
<table background="./Red-Getting-Started.html" border="0" cellpadding="15" cellspacing="2" height="100%" width="100%">
<tbody>
<tr>
<td background="./Red-Getting-Started.html" valign="top">
<!--Page generated by REBOL-->
<title>Red 语言入门</title>
<style type="text/css">
html, body, p, td, li {font-family: arial, sans-serif, helvetica; font-size: 10pt;}
h1 {font-size: 16pt; Font-Weight: bold;}
h2 {font-size: 14pt; color: #2030a0; Font-Weight: bold; width: 100%;
border-bottom: 1px solid #c09060;}
h3 {font-size: 12pt; color: #2030a0; Font-Weight: bold;}
h4 {font-size: 10pt; color: #2030a0; Font-Weight: bold;}
h5 {font-size: 10pt; Font-Weight: bold;}
tt {font-family: "courier new", monospace, courier; color: darkgreen;}
pre {font: bold 10pt "courier new", monospace, console;
background-color: #e0e0e0; padding: 16px; border: solid #a0a0a0 1px;}
.toc1 {margin-left: 1cm; font-size: 12pt; font-weight: bold;}
.toc2 {margin-left: 2cm; font-size: 10pt; Font-Weight: bold; text-decoration: none;}
.toc3 {margin-left: 3cm; font-size: 10pt; text-decoration: none;}
.toc4 {margin-left: 4cm; font-size: 10pt; color: grey; text-decoration: none;}
.output {color: #000080; font-weight: normal;}
.note {background-color: #f0e090; width: 100%; padding: 16px; border: solid #a0a0a0 1px;}
.tail {color: gray; font-size: 8pt;}
</style>
<table width="660" cellpadding="4" cellspacing="0" border="0">
<tbody><tr>
</tr><tr height="10"><td></td></tr>
<tr><td><h1>Red 语言入门</h1>
<blockquote><b>作者:Nick Antonaccio<br>更新于 4-1-2016</b></blockquote>
<h2>内容:</h2>
<a class="toc1" href="./Red-Getting-Started.html#section-1">1. 下载 Red 解释器</a><br>
<a class="toc1" href="./Red-Getting-Started.html#section-2">2. 从源代码编译本机 Red 应用程序</a><br>
<a class="toc1" href="./Red-Getting-Started.html#section-3">3. Red 语言基础</a><br>
<a class="toc2" href="./Red-Getting-Started.html#section-3.1">3.1 函数</a><br>
<a class="toc2" href="./Red-Getting-Started.html#section-3.2">3.2 数据持久性 - Red 语言不需要数据库系统</a><br>
<a class="toc2" href="./Red-Getting-Started.html#section-3.3">3.3 变量</a><br>
<a class="toc2" href="./Red-Getting-Started.html#section-3.4">3.4 条件判断</a><br>
<a class="toc2" href="./Red-Getting-Started.html#section-3.5">3.5 使用文本字符串和串接</a><br>
<a class="toc2" href="./Red-Getting-Started.html#section-3.6">3.6 列表</a><br>
<a class="toc2" href="./Red-Getting-Started.html#section-3.7">3.7 循环</a><br>
<a class="toc2" href="./Red-Getting-Started.html#section-3.8">3.8 用户界面</a><br>
<a class="toc2" href="./Red-Getting-Started.html#section-3.9">3.9 用户自定义函数</a><br>
<a class="toc2" href="./Red-Getting-Started.html#section-3.10">3.10 处理错误</a><br>
<a class="toc1" href="./Red-Getting-Started.html#section-4">4. Rebol 中的一些 Rote GUI,文件和数据列表示例</a><br>
<a class="toc2" href="./Red-Getting-Started.html#section-4.1">4.1 基本 GUI 示例</a><br>
<a class="toc2" href="./Red-Getting-Started.html#section-4.2">4.2 使用列表和循环的一些 GUI 示例</a><br>
<a class="toc2" href="./Red-Getting-Started.html#section-4.3">4.3 构建基本 CRUD(创建,读取,更新,删除)联系人应用</a><br>
<a class="toc1" href="./Red-Getting-Started.html#section-5">5. 几个更完整的应用程序示例</a><br>
<a class="toc2" href="./Red-Getting-Started.html#section-5.1">5.1 提示计算器</a><br>
<a class="toc2" href="./Red-Getting-Started.html#section-5.2">5.2 图块游戏</a><br>
<a class="toc2" href="./Red-Getting-Started.html#section-5.3">5.3 通用计算器</a><br>
<a class="toc2" href="./Red-Getting-Started.html#section-5.4">5.4 硬币翻转</a><br>
<a class="toc2" href="./Red-Getting-Started.html#section-5.5">5.5 额外的应用学习示例</a><br>
<h2 id="section-1">1. 下载 Red 解释器</h2>
<blockquote>
<p>Red 语言解释器的最新官方二进制下载可在<a href="http://www.red-lang.org/p/download.html" target="_blank">http://www.red-lang.org/p/download.html</a>找到。 目前,该链接的最新版本为 0.6.0。 您可以将代码示例直接粘贴到控制台中,或将脚本文件拖放到解释器可执行文件上以运行它们。</p>
</blockquote>
<h2 id="section-2">2. 从源代码编译本机 Red 应用程序</h2>
<blockquote>
<p>Red 语言正在积极开发,并定期提供新功能。 要在任何支持的平台上使用 Red 语言的最新开发版本,或为您选择的平台生成本机二进制文件,您可以使用 Red 源代码编译 Red 脚本:</p>
<ul>
<li>下载源代码仓库在 <a href="https://github.com/red/red" target="_blank">https://github.com/red/red</a>找到。 点击“下载 zip”链接,然后将包解压缩到硬盘上的一个文件夹里。 为了本教程的目标,我们假设您已经在 Windows 机器上将该软件包解压缩到 C:\ 中。</li>
<li>下载 Rebol 解释器从 <a href="http://www.rebol.com/download-core.html" target="_blank">http://www.rebol.com/download-core.html</a>,并将其直接复制到上面解压缩的源文件夹的根目录(即 C:\red\)</li>
</ul>
<p>搞定。 编译脚本:</p>
<ul>
<li>打开 Rebol 解释器</li>
<li>在控制台里,输入 "do/args %red.r {%yourscript.red}"</li>
</ul>
<p>编译完成后,您将看到创建的可执行文件的文件名(即 yourscript.exe)。</p>
<p>从源程序运行 Red 程序就是这样了。</p>
<p>注意: 控制台将让您更快速,自然地看到结果。 您会注意到一些交互式示例包含在“do []”中。 这样就可以在需要用户输入的“ask”等函数执行之前将代码粘贴到解释器中。</p>
</blockquote>
<h2 id="section-3">3. Red 语言基础</h2>
<blockquote>
</blockquote>
<h3 id="section-3.1">3.1 函数</h3>
<blockquote>
<p>函数是对数据“对象”(或“参数”)执行操作的关键字。 print 函数打印一些文本到 Red 语言控制台。 在下面的代码中,print 是函数,“Hello World”是对象。 尝试将此示例粘贴到 Red 语言控制台中:</p>
<pre>print "Hello World"
</pre>
<p>halt 函数不需要任何对象。 它只是暂停程序并显示控制台:</p>
<pre>halt
</pre>
<p>request-file 函数弹出一个对话框,允许用户从本地文件系统中选择一个文件:</p>
<pre>request-file
</pre>
<p>在 Red 语言中,一些函数具有可选的“进阶”功能,允许该函数接受各种潜在的有用的参数。 以下是 request-file 函数的一些进阶。 在控制台中试试:</p>
<pre>request-file/file %test.red
request-file/file/save %test.red
</pre>
<h4 id="section-3.1.1">3.1.1 返回值</h4>
<p>ask 函数 <i>返回</i> 或输出用户输入的文本:</p>
<pre>ask "输入一些文字: "
</pre>
<p>在控制台中工作时,函数的返回值将被自动打印出来。 在脚本文件中工作时,可以将控制台的函数返回值 <i>print</i> (打印)出来:</p>
<pre>Red [] ; 标题,因为下面将从一个脚本文件运行
print ask "输入一些文字: "
halt ; 这样就可以在打印后暂停解释器的运行</pre>
<p>下面的示例使用 print 函数显示 request-dir 函数的输出,并直接返回给用户:</p>
<pre>print request-dir
</pre>
<p>请注意,在上面的 print 函数在完成其操作之前,首先需要从 request-dir 函数返回一个值。 因为这个要求,当这个代码运行时,print 函数被暂时挂起,用户看到的第一件事就是 request-dir 函数弹出窗口。</p>
<p>使用一个函数的输出值作为另一个函数的输入参数是 Red 语言编写代码的常规方式。</p>
</blockquote>
<h3 id="section-3.2">3.2 数据持久性 - Red 语言不需要数据库系统</h3>
<blockquote>
<p>要将文本数据保存到硬盘,U 盘或其他存储介质中,请使用 write 函数。 write 函数有两个参数: 文件位置和要写入该文件的数据。 本地文件名前面带有百分号前缀(%):</p>
<pre>write %mydata "这是我后面要保存的文本。"
</pre>
<p>要稍后检索文本,请使用 read 函数。 您可以使用 print 函数打印从文件读取的格式化数据,或者使用 probe 函数查看原始的无格式数据:</p>
<pre>print read %mydata
probe read %mydata
</pre>
<p>您可以从网络/Internet URL 的服务器读取,和从计算机上本地驱动器读取的方式相同:</p>
<pre>read http://site.com/mydata.txt
</pre>
<p>/binary 进阶允许您以字节读取数据:</p>
<pre>read/binary ./Home.html
</pre>
<p>结合 write 和 read 函数执行下载:</p>
<pre>write %r.html read/binary ./Home.html
</pre>
<p>要存储由 Red 语言自然理解的任何格式的复杂结构化数据类型,请使用 save 函数:</p>
<pre>save %mycontacts ["John" "Bill" "Jane" "Ron" "Sue"]
</pre>
<p>要加载保存的结构化数据,请使用 load 函数:</p>
<pre>probe load %mycontacts
</pre>
<p>您会看到,Red 语言提供搜索,排序,比较,组合,添加,删除,更改,加载,保存和以其他方式处理持久数据所需的所有功能。 所有这些功能一起提供与数据库系统(如 MySQL,SQLite 等)相同的功能,具有更短和更一致的学习曲线,以及更精细的数据处理算法的细粒度控制,所有这些都在一个微小的 100% 便携式工具集中。 学习的函数以及用于管理 Red 语言中持久性数据结构的一系列函数也用于解决语言中许多其他类型的问题领域(访问网络套接字连接,电子邮件帐户,图形显示,控制台和 IO 交互等) )。 这个单一的技能广泛应用于Red 语言,比如其他语言中的 SQL(SQL 是一种领域专用语言,只能应用于数据库操作中处理信息)。 这个贯彻始终应用的概念是帮助 Red 语言保持简单性的基本功能。 管理多个客户端用户对数据的并发访问的问题是 <a href="http://re-bol.com/rebol-multi-client-databases.html" target="_blank">容易解决的</a> 在 Red 语言中。</p>
</blockquote>
<h3 id="section-3.3">3.3 变量</h3>
<blockquote>
<p>变量是分配用于表示程序中数据的标识字符(一些字符串)。 在 Red 语言中,使用冒号符号创建标识字符。 尝试将这些示例粘贴到 Red 控制台中:</p>
<pre>name: "John"
probe name
</pre>
<p>变量可以<strong>变化</strong>以保存不同的值(它们所指的数据是 <i>可变的</i> )。 上面的代码会输出 "John"。 以下代码会输出 "Bill" :</p>
<pre>name: "Bill"
probe name
</pre>
<p>请注意,Red 语言 <i>不区分大小写</i> 。 解释器将标识符中的小写字母和大写字母视为相同:</p>
<pre>name: "George"
print name
print Name
print NAME
print NaMe
</pre>
<p>您可以为请求函数返回的数据分配一个变量名标签。 此代码打印用户选择的文件的名称:</p>
<pre>name: request-file
probe name
</pre>
<p>您可以为从文件读取的数据分配一个标签:</p>
<pre>data: read %mydata
probe data
</pre>
<p>您可以为任何 <i>代码块</i> 分配一个标签,并使用 do 函数来评估(运行)该代码:</p>
<pre>mycode: [print "Hello" halt]
do mycode
</pre>
</blockquote>
<h3 id="section-3.4">3.4 条件判断</h3>
<blockquote>
<p>大多数程序使用“if/then”判断: if (this) is true [do this]:</p>
<pre>account: -10
if account < 0 [print "Your account is overdrawn."]
</pre>
<p>"Either" 就像其他语言的 if/else 判断: if (this) is true [do this] [otherwise do this]. 请注意,让每个单独的动作块都缩进,以便您可以清楚地看到两个不同的动作。 还要注意,这个交互式示例包含在一个“do []”块中:</p>
<pre>do [
pass: ask "Enter Password: "
either pass = "secret" [
print "Welcome back."
] [
print "Incorrect password."
]
]
</pre>
<p>“Case”可以用于各种行为之间的选择,具体情况如下:</p>
<pre>name: "john"
case [
find name "a" [print {Your name contains the letter "a"}]
find name "e" [print {Your name contains the letter "e"}]
find name "i" [print {Your name contains the letter "i"}]
find name "o" [print {Your name contains the letter "o"}]
find name "u" [print {Your name contains the letter "u"}]
true [print {Your name doesn't contain any vowels!}]
]
</pre>
<p>Red 语言还有许多其他条件判断结构,但这些结构足以应对大多数情况。</p>
</blockquote>
<h3 id="section-3.5">3.5 使用文本字符串和串接</h3>
<blockquote>
<p>可以使用大括号 {Curly braces} 而不是引号括起包含引号字符或多行字符串的文本字符串:</p>
<pre>print {She said "Hi"}
print {
line 1
line 2
line 3
}
</pre>
<p>trim 函数提供了许多有助于从字符串中删除空格的进阶:</p>
<pre>print trim {
line 1
line 2
line 3
}
print trim/all {
line 1
line 2
line 3
}
</pre>
<p>“^/”字符用于表示回车符:</p>
<pre>print "line 1^/line 2^/line 3"
</pre>
<p>“prin”函数用于打印不带回车的文本:</p>
<pre>prin "no newline " prin "add a newline manually" prin newline ; "^/"
</pre>
<p>“Concatenation”是连接多个数据块的过程。 Red 语言使用 append 函数连接文本:</p>
<pre>print append "Chosen file name: " request-file
</pre>
<p>大多数程序使用由变量标签表示的连接值,通常由用户输入获得,由条件操作产生,由各种可能的程序状态产生,或在程序运行期间动态变化的其他数据项。 请注意,连接的项目可以为了可读性放置在多行并缩进:</p>
<pre>do [
name: ask "Your Name: "
file: request-file
print append append name ", your chosen file is: " file
]
</pre>
<p>当打印多个值时,不需要连接。 只需要将每个单独的值放在一个块中,打印时会自动加入:</p>
<pre>name: "John" birthday: "1-Jan-1999" phone: "123-234-3456"
prin ["name: " name " birthday: " birthday " phone: " phone]
</pre>
<p>您可以连接代码字符串,并使用 do 函数(这是一种简单的“元编程”形式)来运行该代码):</p>
<pre>do [
code: ask {Enter some code: } ; for example, {print "hello"}
do append {print "Here's your running code..."} code
]
</pre>
</blockquote>
<h3 id="section-3.6">3.6 列表</h3>
<blockquote>
<p>大多数计算机应用程序处理某种数据列表: 图形程序中的坐标列表,库存程序中的项目列表(以及它们的价格,尺寸,运输日期等),财务程序中的姓名(以及帐号,密码,交易详细信息等),工具程序中的文件列表,电子邮件程序中的电子邮件地址等。 Red 语言的主要列表结构称为“序列”。 Red 语言内置了一些功能,允许您添加,删除,更改,搜索,排序,比较,组合,加载,保存或以其他方式操作序列数据。 操作文本(文字列表),游戏画面上的图形(绘图块中的图像和屏幕位置列表)中的字符,网络端口之间传输的数据等。 所有这些都只需要知道一套简单的函数集合。</p>
<p>用于在 Red 语言中存储一系列数据项的基本代码结构称为“块”。 只需将方括号放在项目列表中,并为其分配一个变量标签:</p>
<pre>names: ["John" "Dave" "Jane" "Bob" "Sue"]
codes: [2804 9439 2386 9823 4217]
files: [%employees %vendors %contractors %events]
</pre>
<p>您可以使用简单的函数和结构从列表中选择,查找和排序项目:</p>
<pre>print pick names 3 ; 这两行做的是
print names/3 ; 同样的事情
print find names "Dave"
print sort names
print sort codes
</pre>
<p>请注意,在上面的排序示例中,每种类型的数据都会自动排序(名称按字母顺序排列,数字按顺序排列)。</p>
<p>使用 save 和 load 函数保存和加载数据块:</p>
<pre>names: ["John" "Dave" "Jane" "Bob" "Sue"]
save %mynames names
loaded-names: load %mynames
probe loaded-names
</pre>
<p>掌握序列操作是熟练掌握 Red 语言的核心技能。 这些函数会变得很常用: pick, find, at, index?, length?, append, remove, insert, extract, copy, replace, select, sort, reverse, head, next, back, last, tail, skip, change, poke, clear, join, intersect, difference, exclude, union, unique, empty?, write, read, save, load.</p>
</blockquote>
<h3 id="section-3.7">3.7 循环</h3>
<blockquote>
<p>循环用于对列表中的每个连续项执行某项操作。 Foreach 是 Rebol 语言中最常用的循环类型:</p>
<pre>names: ["John" "Dave" "Jane" "Bob" "Sue"]
foreach name names [print name]
</pre>
<p>循环中的变量标签可以设置为任意字。 例如,这个例子与上面的代码完全相同:</p>
<pre>n: ["John" "Dave" "Jane" "Bob" "Sue"]
foreach i n [print i]
</pre>
<p>很多时候,你会检查列表中的每个项目的条件,并根据每个项目的判断进行对应的操作:</p>
<pre>names: ["John" "Dave" "Jane" "Bob" "Sue"]
foreach name names [
if find name "j" [print name]
]
numbers: [323 2498 94321 31 82]
foreach number numbers [
if number > 300 [print form number]
]
</pre>
<p>您可以在列表中组织数据以生成行和列。 以下 foreach 循环将“mycontacts”列表中每3个连续的数据片段标记为姓名,地址和电话号码。 请注意, "" 用作空的占位符:</p>
<pre>mycontacts: [
"John Smith" "123 Tomline Lane Forest Hills, NJ" "555-1234"
"Paul Thompson" "234 Georgetown Pl. Peanut Grove, AL" "555-2345"
"Jim Persee" "345 Pickles Pike Orange Grove, FL" "555-3456"
"George Jones" "456 Topforge Court Mountain Creek, CO" ""
"Tim Paulson" "" "555-5678"
]
foreach [name address phone] mycontacts [
print name
]
</pre>
<p>您可以使用 extract 函数,而不是 foreach 循环作为获取数据列的快捷方式:</p>
<pre>mycontacts: [
"John Smith" "123 Tomline Lane Forest Hills, NJ" "555-1234"
"Paul Thompson" "234 Georgetown Pl. Peanut Grove, AL" "555-2345"
"Jim Persee" "345 Pickles Pike Orange Grove, FL" "555-3456"
"George Jones" "456 Topforge Court Mountain Creek, CO" ""
"Tim Paulson" "" "555-5678"
]
probe extract mycontacts 3 ; 每3个项目
; (上述第1列数据)探针提取/索引 mycontacts 3 3 ; 每3个项目,从第3个开始
; (上述第3列数据)</pre>
<p>您可以使用很像 foreach 的 repeat 循环,来计算列表中的项目。 此示例将计数器变量 i 从 1 计数到姓名区块的长度,每次通过循环将变量递增 1:</p>
<pre>names: ["John" "Dave" "Jane" "Bob" "Sue"]
repeat i (length? names) [
print append append form i ": " pick names i
]
names: ["John" "Dave" "Jane" "Bob" "Sue"]
repeat i (length? names) [
print append append pick names i " next: " pick names (i + 1)
]
</pre>
<p>一个 forever 的循环永远重复,直到遇到一个 break 函数:</p>
<pre>count: 99
forever [
print append form count " bottles of beer on the wall"
count: count - 1
if count = 0 [break]
]
</pre>
</blockquote>
<h3 id="section-3.8">3.8 用户界面</h3>
<blockquote>
<h4 id="section-3.8.1">3.8.1 控制台应用程序</h4>
<p>工具程序脚本通常会将快速(非图形)的数据显示到 Red 语言控制台,或者可能需要对控制台文本提示中询问的问题进行简短的回答。 您可以使用 ask 和 print 函数来做简单的控制台 i/o 。 将此代码保存到文件并运行它(在控制台中键入“do filename.r”):</p>
<pre>Red []
user: ask "Username (iwu83): "
pass: ask "Password (zqo72): "
either all [user = "iwu83" pass = "zqo72"] [
print "Welcome back"
] [
print "Incorrect Username/Password"
]
ask ""
</pre>
<h4 id="section-3.8.2">3.8.2 GUI 应用程序</h4>
<p>对于大多数“应用程序”,GUI(图形用户界面)屏幕用于输入和输出数据并控制程序流程。 按钮,文本字段,下拉选择器和其他“小部件”让用户可以操作程序。 Red 语言提供了一个简单的内置代码方言来创建交互式 GUI 。 “view”一词创建一个窗口布局。 一个代码块保存组件描述。 below 和 across 关键字用于设置窗口组件的默认顺序位置。 将本节中的每个示例保存为 .red 文件,并编译它们以查看创建的屏幕:</p>
<pre>Red [title: "测试" needs: 'view]
view [
below
button
field
text“Red 语言真的很容易编程”。
text-list
check
]
</pre>
<p>您可以通过适当的在每个组件后面跟随修饰参数来调整屏幕布局中任何窗口组件的视觉特征:</p>
<pre>Red [title: "测试" needs: 'view]
view [
below
button red "点击我"
field 400 "在这里输入一些文字"
text font-size 16 "Red 语言真的很容易编程。" purple
text-list 400x300 data ["行 1" "行 2" "另一行"]
check yellow
]
</pre>
<p>当单击或其他方式激活时,您可以使用组件执行函数或任何代码块。 只需将函数放在组件之后的另一组方括号中。 这就是如何让你的 GUI“做某事”:</p>
<pre>Red [title: "测试" needs: 'view]
view [
button "点击我" [print "你按下了按钮。"]
]
</pre>
<p>您可以使用路径(“/”)语法来引用组件中包含的数据。 将变量标签分配给要引用的任何组件:</p>
<pre>Red [title: "测试" needs: 'view]
view [
below
text "一些动作示例。 尝试使用每个小部件:"
button red "点击我" [
print "你按下了红色按钮。"
]
f: field 400 "在这里输入一些文字,然后按下 [Enter]" [
print f/text
]
t: text-list 400x300 data ["选择这个" "然后这个" "现在这个"][
print pick t/data t/selected
]
check yellow [print "你点击了黄色复选框。"]
button "退出" [unview]
]
Red [title: "测试" needs: 'view]
view [
below
a: area ; 标有“a”的区块组件
f: field ; 标有“f”的字段组件
across
button "显示" [print a/text]
button "保存" [write %somedatafile.txt a/text]
button "加载" [f/text: read %somedatafile.txt]
]
Red [title: "测试" needs: 'view]
view [
below
t: text-list data [1 2 3] ; 标有“t”的文本列表
button "显示选中" [print pick t/data t/selected]
]
</pre>
<p>您可以使用循环结构动态构建布局,然后显示生成的 GUI 代码:</p>
<pre>Red [title: "测试" needs: 'view]
gui: copy []
foreach color [red green blue] [
append gui reduce ['text color]
]
view layout gui
</pre>
<p>如果要使用 Red 语言创建用户应用程序,您将需要了解更多关于创建GUI 界面的信息,但您可以通过上述基础知识完成许多工作。</p>
<p>看看一些<a href="./Short%20Red%20Code%20Examples.html" target="_blank">额外的 GUI 示例</a>这些演示了有趣的组件以及如何使用它们。</p>
<p>本文下半部分的例子将通过许多常见的 GUI 技术来解释和演示。</p>
<h4 id="section-3.8.3">3.8.3 服务器和 CGI Web 应用程序</h4>
<p>Red 语言具有内置的网络和数据/代码传输功能,可以轻松创建客户端-服务器应用程序。 客户端应用程序可以用 Red,HTML/CSS/Javascript 或使用标准网络协议(HTTP://,TCP,UDP 等)连接的任何其他语言编写。 Red 语言还提供本地“CGI”功能,以便服务器脚本可以在典型的 Apache 主机或任何其他 Web 服务器堆栈上运行,并接受来自 HTML Web 表单,Ajax 请求等的输入,然后打印 HTML 或格式化数据响应以显示在用户的网络浏览器中。</p>
<p>本文末尾的完整部分专门用于创建 CGI 应用程序(独立网络应用程序在“快速入门”第2部分中介绍)。 这允许您使用 Red 语言创建基于 Web 的实用数据管理应用程序,可以在移动设备或任何具有浏览器的平台上访问。</p>
<h4 id="section-3.8.4">3.8.4 无界面应用</h4>
<p>某些类型的实用程序脚本可能不需要与用户的任何交互。 例如,在后台执行计划文件维护,上传例行数据备份,检查和更新当前系统时间等的应用程序不一定需要向您显示它们正在运行。 Red 脚本可以在内存中运行,无需任何前端显示。</p>
</blockquote>
<h3 id="section-3.9">3.9 用户自定义函数</h3>
<blockquote>
<p>您可以使用“func”代码结构在 Red 语言中创建自己的函数。 为新函数分配一个后跟冒号符号的单词标签。 函数将处理的数据参数的标签列在代码块中,然后计算或函数执行的其他操作包含在后面的代码块中。</p>
<p>这里是一个名为“triple”的函数,它将任意给定数字为参数的数字乘以3(在此称为“x”):</p>
<pre>triple: func [x] [
print 3 * x
]
</pre>
<p>现在,您可以将“triple”函数应用于任何参数值条件下,就像该函数是 Red 语言中内置的内置函数一样:</p>
<pre>triple 4
triple 5
triple 6
print "我只是把数字 4 (12), 5 (15), 和 6 (18) 增加了三倍"
</pre>
<p>想像上面的函数定义中的参数 x(参数),就像一些程序的命令行选项一样 - 它代表一些你发送给程序的变量数据来做一些工作。 在 triple 函数中,参数表示任何数字乘以3,而 x 是用于表示该参数值的变量占位符。</p>
<p>does 结构是 func 的快捷方式,当不需要数据参数时:</p>
<pre>cls: does [loop 100 [print newline]]
cls
</pre>
<h4 id="section-3.9.1">3.9.1 返回值</h4>
<p>Red 函数定义中的最后一个值被视为其“返回”值。 下面的 check 函数采用一系列字符串值作为参数(这里标记为 list ),并检查它是否包含任何坏字(在这个例子中,坏字由字符“ --”指定)。 该函数通过将变量 answer 设置为“安全”开始,然后使用 foreach 循环和 if 条件查看是否在序列中的任何字符串中找到“--”。 如果在任何时候发现坏字符,answer 变量设置为“非安全”。 在函数结束时,返回 answer 变量。 该函数然后在 names1 和 names2 列表上运行,并显示用户返回的结果:</p>
<pre>check: func [list] [
answer: "安全"
foreach l list [
if find l "--" [answer: "非安全"]
]
answer
]
names1: ["Joe" "Dan" "Sh--" "Bill"]
names2: ["Paul" "Tom" "Mike" "John"]
print append "names1 is " check names1
print append "names2 is " check names2
</pre>
<h4 id="section-3.9.2">3.9.2 扩展库</h4>
<p>您可以将有用的函数(“库”)的集合保存到文件中,并使用“do”导入。 这样可以节省您将常用函数定义代码重新输入或粘贴到每个新程序中的时间。 只需将上面的 check 函数代码保存到名为“myfunctions.red”的文件中 - 请确保在将代码保存到文件时包含 Red [] 头:</p>
<pre>Red []
check: func [list] [
answer: "安全"
foreach l list [
if find l "--" [answer: "非安全"]
]
answer
]
</pre>
<p>上一节的程序如下所示:</p>
<pre>Red []
do %myfunctions.red
names1: ["Joe" "Dan" "Sh--" "Bill"]
names2: ["Paul" "Tom" "Mike" "John"]
print append "names1 is " check names1
print append "names2 is " check names2
</pre>
<p>导入的文件可以在本地文件系统(即硬盘驱动器,移动存储器等)上,也可以在 网络/Internet 网址上。 例如,如果您将“myfunctions.r”文件保存在您的网站服务器上,则可以像这样导入:</p>
<pre>do http://site.com/myfunctions.r
</pre>
<p>实际上,您可以在导入的文件中包含所需的 <i>任何</i> 代码(而不仅仅是函数定义)。 您可以将上述整个程序放入网站上的文件中,并通过“do”导入文件的 URL 来运行。 用 do 导入文件与将文件的内容复制并粘贴到代码中完全一样,然后执行它。</p>
</blockquote>
<h3 id="section-3.10">3.10 处理错误</h3>
<blockquote>
<p>error? 和 try 函数可以一起使用来检测 Red 语言代码中的运行时错误。 使用 if 或其他条件判断来处理任何错误事件:</p>
<pre>if error? try [0 / 0] [alert "除零错误"]
</pre>
<p>您可以通过为 try 函数的结果分配一个标签来检查错误属性:</p>
<pre>if error? err: try [0 / 0] [probe err]
</pre>
<p>attempt 函数也可以用来处理错误:</p>
<pre>attempt [1 / 1]
attempt [0 / 0]
</pre>
</blockquote>
<h2 id="section-4">4. Rebol 中的一些 Rote GUI,文件和数据列表示例</h2>
<blockquote>
<p>本节演示了通常用于在 Red 语言中创建应用程序的各种代码模式。 它们使用了已经介绍过的用户界面,函数,变量,字符串连接,列表,循环,条件判断以及其他代码结构。 这些例子可以随机选择或者尝试 - 只需将它们粘贴到脚本文件中,然后再编译/运行代码即可。 您可以在构成本教程其余部分的 20 多个示例应用程序中使用每个片段的变体形式。 第一个例子着重于执行与用户界面的基本交互,然后进展到处理更有趣的数据操作。 要注意列表和循环的使用,就像上面这些例子中那样。</p>
</blockquote>
<h3 id="section-4.1">4.1 基本 GUI 示例</h3>
<blockquote>
<p>创建一个带有按钮的窗口:</p>
<pre>Red [needs: 'view]
view [
button "点击我"
]
</pre>
<p>点击按钮时,执行以下操作:</p>
<pre>Red [needs: 'view]
view [
button "点击我" [print "我被点击了!"]
]
</pre>
<p>这是一个带有按钮和文本输入字段的窗口,标记为 f 。 单击按钮时,打印“f”字段中的当前文本。 尝试在字段中键入内容,然后单击按钮:</p>
<pre>Red [needs: 'view]
view [
f: field "在这里输入,然后点击按钮"
button "点击我" [print f/text]
]
</pre>
<p>单击按钮时,将该字段的内容写入文件 mytext.txt,然后显示文件已被保存:</p>
<pre>Red [needs: 'view]
view [
f: field "在这里输入,然后点击按钮"
button "点击我"
]
write %mytext.txt f/text
print "已保存"
]
]
</pre>
<p>添加另一个按钮将文件内容读回到该字段中。 现在可以关闭该程序,再次运行并检索保存的文本:</p>
<pre>Red [needs: 'view]
view [
f: field
button "保存" [
write %mytext.txt f/text
print "已保存"
]
button "加载" [
f/text: form read %mytext.txt
]
]
</pre>
<p>这是与上述完全相同的程序,除了使用文本区域组件,而不是单行字段。 这形成一个简单的文本编辑器:</p>
<pre>Red [needs: 'view]
view [
a: area
button "保存" [
save %mytext.txt a/text
print "已保存"
]
button "加载" [
a/text: load %mytext.txt
]
]
</pre>
<p>这里的文本 <i>附加</i> 到 mylist.txt。 每次新的保存操作都不会覆盖文件内容,而是加载上一个文件,然后添加一个新的行。 append 函数将加载的文本与新文本(以及一些换行符)连接在一起,以便创建多行日志文件:</p>
<pre>Red [needs: 'view]
view [
below
f: field "在这里输入一些行。。。"
button "保存" [
save %mylist.txt append append load %mylist.txt f/text "^M^/"
print "已保存"
]
a: area "加载时,所有日志内容都将显示在此处。。。"
button "加载" [
a/text: form load %mylist.txt
]
]
</pre>
</blockquote>
<h3 id="section-4.2">4.2 使用列表和循环的一些 GUI 示例</h3>
<blockquote>
<p>现在这里有一些在 GUI 布局中显示列表的示例,使用 text-list 组件:</p>
<pre>Red [needs: 'view]
view [
text-list data ["John" "Dave" "Jane" "Bob" "Sue"]
]
</pre>
<p>您可以显示以前创建的列表:</p>
<pre>Red [needs: 'view]
mylist: copy ["John" "Dave" "Jane" "Bob" "Sue"]
view [
text-list data mylist
]
</pre>
<p>在显示布局之前,可以使用 do 代码块来运行代码并对 GUI 进行更改。 在这里,创建一个空白的文本列表组件,然后在显示之前添加一些值数据:</p>
<pre>Red [needs: 'view]
mylist: copy ["John" "Dave" "Jane" "Bob" "Sue"]
view [
t: text-list data []
do [append t/data mylist]
]
</pre>
<p>您还可以使用其他组件的操作块将条目添加到窗口组件中:</p>
<pre>Red [needs: 'view]
mylist: copy ["John" "Dave" "Jane" "Bob" "Sue"]
view [
t: text-list data []
button "添加条目到列表" [append t/data mylist]
]
</pre>
<p>此示例使用 extract 函数创建一个仅包含原始列表中的姓名的 <i>新列表</i> ,然后显示在文本列表窗口组件中:</p>
<pre>mylist: copy ["John" 2804 "Dave" 9439 "Jane" 2386 "Bob" 9823 "Sue" 4217]
names: extract mylist 2
view [
t: text-list data names
]
</pre>
<p>这个例子使用 foreach 循环结构来做同样的事情。 首先,使用“copy []”创建一个空白的姓名列表,然后使用 foreach 和 append 将项目添加到此列表。 我们将使用此代码模式,以帮助熟悉“foreach”的使用,因为它在所有类型的 Red 语言应用程序中都很常见:</p>
<pre>Red [needs: 'view]
mylist: ["John" 2804 "Dave" 9439 "Jane" 2386 "Bob" 9823 "Sue" 4217]
names: copy []
foreach [n c] mylist [append names n]
view [
t: text-list data names
]
</pre>
<p>列表中项目的“index”是其列表中的数字位置。 文本列表组件中点击的条目索引使用“/selected”引用:</p>
<pre>Red [needs: 'view]
mylist: ["John" 2804 "Dave" 9439 "Jane" 2386 "Bob" 9823 "Sue" 4217]
names: extract mylist 2
view [
t: text-list data names [probe t/selected]
]
</pre>
<p>您可以使用所选索引从文本列表数据块中选取实际值:</p>
<pre>Red [needs: 'view]
mylist: ["John" 2804 "Dave" 9439 "Jane" 2386 "Bob" 9823 "Sue" 4217]
names: copy []
foreach [n c] mylist [append names n]
view [
t: text-list data names [probe pick t/data t/selected]
]
</pre>
<p>当组件指向自己时,可以使用“face”关键字。 下面是与上面相同的例子,使用 face 而不是 t:</p>
<pre>Red [needs: 'view]
mylist: ["John" 2804 "Dave" 9439 "Jane" 2386 "Bob" 9823 "Sue" 4217]
names: copy []
foreach [n c] mylist [append names n]
view [
t: text-list data names [
probe form index? find mylist (pick face/data face/selected)
]
]
</pre>
<p>您可以通过在当前项目的索引中添加 1 来选择列表中的下一个项目。 在下面的 mylist 示例中,每个数字值始终位于下一个索引位置,紧随每个姓名(即“Jane”在示例列表中的位置 5,她的编号 2386 位于位置 6)。 在代码中,这被认为是 1 +(Jane 的索引位置):</p>
<pre>Red [needs: 'view]
mylist: ["John" 2804 "Dave" 9439 "Jane" 2386 "Bob" 9823 "Sue" 4217]
names: copy []
foreach [n c] mylist [append names n]
view [
t: text-list data names [
print form pick mylist (
1 + index? find mylist (pick t/data t/selected)
)
]
]
</pre>
</blockquote>
<h3 id="section-4.3">4.3 构建基本 CRUD(创建,读取,更新,删除)联系人应用</h3>
<blockquote>
<p>以下是与上述相同的想法,但每个姓名有更多数据字段(3 列数据,而不是 2 列)。 姓名,地址和电话号码可以在连续的姓名,姓名+ 1 和姓名+ 2 的位置找到:</p>
<pre>Red [needs: 'view]
mycontacts: [
"John Smith" "123 Tomline Lane Forest Hills, NJ" "555-1234"
"Paul Thompson" "234 Georgetown Pl. Peanut Grove, AL" "555-2345"
"Jim Persee" "345 Pickles Pike Orange Grove, FL" "555-3456"
"George Jones" "456 Topforge Court Mountain Creek, CO" ""
"Tim Paulson" "" "555-5678"
]
names: copy []
foreach [name address phone] mycontacts [append names name]
view [
t: text-list data names [
print {
"姓名:"
pick t/data t/selected
" 地址:"
pick mycontacts (
1 + index? find mycontacts (pick t/data t/selected)
)
"电话号码:"
pick mycontacts (
2 + index? find mycontacts (pick t/data t/selected)
)
]
]
]
</pre>
<p>不打印一些重新连接的文本,而是在文本输入字段中显示每个数据项:</p>
<pre>Red [needs: 'view]
mycontacts: copy [
"John Smith" "123 Tomline Lane Forest Hills, NJ" "555-1234"
"Paul Thompson" "234 Georgetown Pl. Peanut Grove, AL" "555-2345"
"Jim Persee" "345 Pickles Pike Orange Grove, FL" "555-3456"
"George Jones" "456 Topforge Court Mountain Creek, CO" ""
"Tim Paulson" "" "555-5678"
]
names: copy []
foreach [name address phone] mycontacts [append names name]
view [
below
t: text-list data names [
n/text: pick t/data t/selected
a/text: pick mycontacts (
1 + index? find mycontacts (pick t/data t/selected)
)
p/text: pick mycontacts (
2 + index? find mycontacts (pick t/data t/selected)
)
]
text "姓名:"
n: field
text "地址:"
a: field
text "电话号码:"
p: field
]
</pre>
<p>这是上面的代码版本,使用 panel 组件的更好的布局:</p>
<pre>Red [needs: 'view]
mycontacts: copy [
"John Smith" "123 Tomline Lane Forest Hills, NJ" "555-1234"
"Paul Thompson" "234 Georgetown Pl. Peanut Grove, AL" "555-2345"
"Jim Persee" "345 Pickles Pike Orange Grove, FL" "555-3456"
"George Jones" "456 Topforge Court Mountain Creek, CO" ""
"Tim Paulson" "" "555-5678"
]
names: copy []
foreach [name address phone] mycontacts [append names name]
view [
t: text-list data names [
n/text: pick t/data t/selected
a/text: pick mycontacts (
1 + index? find mycontacts pick t/data t/selected
)
p/text: pick mycontacts (
2 + index? find mycontacts pick t/data t/selected
)
]
panel [
below
text "姓名:"
n: field 200
text "地址:"
a: field 200
text "电话号码:"
p: field 200
]
]
</pre>
<p>通过在字段窗口组件中输入文本,将项目添加到区块组件中(数据显示在文本列表中):</p>
<pre>Red [needs: 'view]
contacts: copy [] names: copy [""]
view [
t: text-list data names [
n/text: pick t/data t/selected
a/text: pick contacts (
1 + index? find contacts pick t/data t/selected
)
p/text: pick contacts (
2 + index? find contacts pick t/data t/selected
)
]
panel [
below
text "姓名:"
n: field 200
text "地址:"
a: field 200
text "电话号码:"
p: field 200
button "添加" [
append contacts reduce [copy n/text copy a/text copy p/text]
clear names
foreach [name address phone] contacts [append names name]
]
]
]
</pre>
<p>该示例使用一个函数来封装重复的代码(这并不会缩短整个程序,但是如果重复的代码例如是 20 行的长度,并且在 5 个不同的地方使用,则整个程序将会在 100 行以内):</p>
<pre>Red [needs: 'view]
extract-names: func [] [
clear names
foreach [name address phone] contacts [append names name]
copy names
]
contacts: copy [] names: copy [""]
view [
t: text-list data names [
n/text: pick t/data t/selected
a/text: pick contacts (
1 + index? find contacts pick t/data t/selected
)
p/text: pick contacts (
2 + index? find contacts pick t/data t/selected
)
]
panel [
below
text "姓名:"
n: field 200
text "地址:"
a: field 200
text "电话号码:"
p: field 200
button "添加" [
append contacts reduce [copy n/text copy a/text copy p/text]
extract-names
]
]
]
</pre>
<p>使用 load %filename 从文件加载列表,并为其分配变量标签。 使用 save %filename [list] 将列表保存到文件。 只有当它不存在(如果在当前直接列表的读取中找不到该文件)时, save %filename [] 会创建一个空文件:</p>
<pre>Red [needs: 'view]
extract-names: func [] [
clear names
foreach [name address phone] contacts [append names name]
if names = [] [names: [""]]
copy names
]
if not find read %. %contacts [save %contacts []]
contacts: load %contacts
names: [""]
names: extract-names
view [
title "联系人"
t: text-list data names [
n/text: copy pick t/data t/selected
a/text: copy pick contacts (
1 + index? find contacts pick t/data t/selected
)
p/text: copy pick contacts (
2 + index? find contacts pick t/data t/selected
)
]
panel [
below
text "姓名:"
n: field 200
text "地址:"
a: field 200
text "电话号码:"
p: field 200
button "添加" [
append contacts reduce [copy n/text copy a/text copy p/text]
extract-names
]
button "保存" [save %contacts contacts]
]
]
</pre>
<p>请注意,在上面的程序中添加了一个带有“联系人”文本的标题组件,显示在 GUI 窗口的标题栏中。</p>
<p>您可以使用上述代码的变体创建各种基本的“CRUD”(创建,阅读,更新,删除)应用程序。 到目前为止,这个程序实际上只是创建和读取,但是我们稍后会添加更多的内容。</p>
</blockquote>
<h2 id="section-5">5. 几个更完整的应用程序示例</h2>
<blockquote>
</blockquote>
<h3 id="section-5.1">5.1 提示计算器</h3>
<blockquote>
<p>此应用程序计算支付餐厅用餐的总金额(包括提示):</p>
<ol>
<li>创建窗口布局。 它包含一个标题组件,3 个文本字段组件,标记为“f”,“t”和“x”以及一个按钮组件。 below 关键字用于将每个连续的组件放置在彼此之下。</li>
<li>f 和 t 字段包含一些默认的金额和百分比值($9 和 0.2(20%))。</li>
<li>当用户点击按钮时,将 x 字段的文本设置为通过乘以 f 字段的浮点值,乘以 t 字段的浮点值 + 1 之后计算的值(即,支付 $9 票据的总和为($9 乘 1.2)):</li>
</ol>
<pre>Red [needs: 'view]
view [
title "提示计算器"
below
f: field "9"
t: field ".2"
button "计算" [
append clear x/text (to float! f/text) * (1 + (to float! t/text))
]
x: field "tip"
]
</pre>
</blockquote>
<h3 id="section-5.2">5.2 图块游戏</h3>
<blockquote>
<p>下面的代码创建一个可玩的图块游戏。 点击任何图块将其移动到空白空间。 按升序重新排列图块:</p>
<ol>
<li>创建 GUI 窗口布局,标题为“图块游戏”和银色背景色。</li>
<li>Red 语言的 GUI 方言中的“style”用于创建一个标记为“t”的新的 button 对象。 每当用户点击 t 组件时,会发生三个动作: 标签 x 设置为框的当前 offset(偏移坐标位置),框的坐标位置设置为 e 组件的位置,并且将 e 组件的位置更改为位置 x。 这三个动作一起有效地 <i>交换</i> 点击的按钮和 e 组件的位置(如下面将看到的,标注为 e 的组层只是一个银色基本组件(框),它在窗口布局中显示为一个空白块)。</li>
<li>Red 语言的 GUI 方言中的 return 关键字用于启动一个新的 line 组件(类似于使用回车符在文本文档中启动新行)。</li>
<li>在窗口布局中的一些 t 窗口框组件被添加到标签为 e 的最终基础组件中。 任何时候你点击一个带编号的按钮,它的位置都会与空的银色框交换。</li>
</ol>
<pre>Red [needs: 'view]
view [
title "图块游戏"
backdrop silver
style t: button 100x100 [
x: face/offset
face/offset: e/offset
e/offset: x
]
t "8" t "7" t "6" return
t "5" t "4" t "3" return
t "2" t "1" e: base silver
]
</pre>
</blockquote>
<h3 id="section-5.3">5.3 通用计算器</h3>
<blockquote>
<p>以下是一个计算器应用程序。 大多数代码都有意义。</p>
<ol>
<li>创建一个 GUI 窗口,标题为“计算器”</li>
<li>窗口布局包括一个标有 f 的字段。 它的大小为 230x50 像素,其中显示的文字的字体大小为 25。</li>
<li>style 关键字用于创建一个名为 b 的新按钮对象,其大小为 50x50 像素,并且当 b 按钮被点击时,将当前按钮的文本附加到 f 组件的文本中。</li>
<li>一组 b 按钮被添加到窗口布局中,每个显示不同的数字或数学运算符。 return 关键字用于启动新的按钮行。</li>
<li>“=”按钮尝试将 f 字段的文本设置为 do (评估)f 字段中显示的当前数学表达式的任何结果。</li>
</ol>
<pre>Red [needs: 'view]
view [
title "计算器"
f: field 230x50 font-size 25 "" return
style b: button 50x50 [append f/text face/text]
b "1" b "2" b "3" b " + " return
b "4" b "5" b "6" b " - " return
b "7" b "8" b "9" b " * " return
b "0" b "." b " / " b "=" [attempt [
calculation: form do f/text
append clear f/text calculation
]]
]
</pre>
<p>注意: 如果要在此计算器应用程序中使用浮点数(分数),请确保在至少一个输入的数字中包含小数点(即 1.0/2,而不是 1/2)</p>
<p>尝试使用任何其他编程语言构建相同的应用程序,您将看到完全没有比 Red 语言的方言更简单的方法来构建窗口化程序。</p>
</blockquote>
<h3 id="section-5.4">5.4 硬币翻转</h3>
<blockquote>
<p>点击此应用程序中的按钮,会在硬币的头像和图案两面之间随机翻转:</p>
<ol>
<li>两个图像从特定的因特网 URL 加载。 标签 h 被分配给加载的头像。 标签 t 被分配给加载的图案。</li>
<li>创建一个窗口布局,标题为“硬币翻转”然后 below 安排布局指令。 它包含一个标记为初始显示 h 图像(硬币头图像)的图像组件,标有 f 的文本字段组件,以及一个显示文本“翻转”的按钮。</li>
<li>当按钮被点击时,它将 f 字段文本设置为 2 个文本字符串“头像”和“图案”的随机排列列表中的第一个项目。</li>
<li>接下来,执行 either 条件判断。 如果 f 字段中的文本是“头像”(在前面的步骤中确定了该随机状态),则将 i 组件的图像设置为 h 图像(头部图像)。 否则(即,如果 f 字段中的文本为“图案”),则 i 小部件中的图像设置为 t(图案图像)。</li>
<li>屏幕(标记为 g )使用 show 函数进行刷新。</li>
</ol>
<pre>Red [needs: 'view]
h: load http://re-bol.com/heads.jpg
t: load http://re-bol.com/tails.jpg
view [
title: "硬币翻转"