-
Notifications
You must be signed in to change notification settings - Fork 5.1k
/
Copy path18_Type_Casting.html
811 lines (528 loc) · 37.8 KB
/
18_Type_Casting.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
<!DOCTYPE HTML>
<html lang="en-US" manifest="../manifest.appcache">
<head>
<meta charset="UTF-8">
<title>《The Swift Programming Language》中文版</title>
<meta content="text/html; charset=utf-8" http-equiv="Content-Type">
<meta name="description" content="">
<meta name="generator" content="GitBook 0.5.2">
<meta name="HandheldFriendly" content="true"/>
<meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no">
<meta name="apple-mobile-web-app-capable" content="yes">
<meta name="apple-mobile-web-app-status-bar-style" content="black">
<link rel="shortcut icon" href="../gitbook/images/favicon.ico" type="image/x-icon">
<link rel="next" href="../chapter2/19_Nested_Types.html" />
<link rel="prev" href="../chapter2/17_Optional_Chaining.html" />
</head>
<body>
<link rel="stylesheet" href="../gitbook/style.css">
<div class="book" data-level="2.18" data-basepath=".." data-revision="1402903834498">
<div class="book-header">
<!-- Actions Left -->
<a href="#" class="btn pull-left toggle-summary" aria-label="Toggle summary"><i class="fa fa-align-justify"></i></a>
<a href="https://github.com/null" target="_blank" class="btn pull-left home-bookmark" aria-label="GitHub home"><i class="fa fa-bookmark-o"></i></a>
<a href="#" class="btn pull-left toggle-search" aria-label="Toggle search"><i class="fa fa-search"></i></a>
<span id="font-settings-wrapper">
<a href="#" class="btn pull-left toggle-font-settings" aria-label="Toggle font settings"><i class="fa fa-font"></i>
</a>
<div class="dropdown-menu font-settings">
<div class="dropdown-caret">
<span class="caret-outer"></span>
<span class="caret-inner"></span>
</div>
<div class="btn-group btn-block">
<button id="reduce-font-size" class="btn btn-default">A</button>
<button id="enlarge-font-size" class="btn btn-default">A</button>
</div>
<ul class="list-group font-family-list">
<li class="list-group-item" data-font="0">Serif</li>
<li class="list-group-item" data-font="1">Sans</li>
</ul>
<div class="btn-group btn-group-xs btn-block color-theme-list">
<button type="button" class="btn btn-default" id="color-theme-preview-0" data-theme="0">White</button>
<button type="button" class="btn btn-default" id="color-theme-preview-1" data-theme="1">Sepia</button>
<button type="button" class="btn btn-default" id="color-theme-preview-2" data-theme="2">Night</button>
</div>
</div>
</span>
<!-- Actions Right -->
<a href="#" target="_blank" class="btn pull-right google-plus-sharing-link sharing-link" data-sharing="google-plus" aria-label="Share on Google Plus"><i class="fa fa-google-plus"></i></a>
<a href="#" target="_blank" class="btn pull-right facebook-sharing-link sharing-link" data-sharing="facebook" aria-label="Share on Facebook"><i class="fa fa-facebook"></i></a>
<a href="#" target="_blank" class="btn pull-right twitter-sharing-link sharing-link" data-sharing="twitter" aria-label="Share on Twitter"><i class="fa fa-twitter"></i></a>
<!-- Title -->
<h1>
<i class="fa fa-spinner fa-spin"></i>
<a href="../" >The Swift Programming Language 中文版</a>
</h1>
</div>
<div class="book-summary">
<div class="book-search">
<input type="text" placeholder="Search" class="form-control" />
</div>
<ul class="summary">
<li data-level="0" data-path="index.html">
<a href="../"><i class="fa fa-check"></i> 序</a>
</li>
<li class="chapter " data-level="1" data-path="chapter1/chapter1.html">
<a href="../chapter1/chapter1.html">
<i class="fa fa-check"></i> <b>1.</b> 欢迎使用 Swift
</a>
<ul class="articles">
<li class="chapter " data-level="1.1" data-path="chapter1/01_swift.html">
<a href="../chapter1/01_swift.html">
<i class="fa fa-check"></i> <b>1.1.</b> 关于 Swift
</a>
</li>
<li class="chapter " data-level="1.2" data-path="chapter1/02_a_swift_tour.html">
<a href="../chapter1/02_a_swift_tour.html">
<i class="fa fa-check"></i> <b>1.2.</b> Swift 初见
</a>
</li>
</ul>
</li>
<li class="chapter " data-level="2" data-path="chapter2/chapter2.html">
<a href="../chapter2/chapter2.html">
<i class="fa fa-check"></i> <b>2.</b> Swift 教程
</a>
<ul class="articles">
<li class="chapter " data-level="2.1" data-path="chapter2/01_The_Basics.html">
<a href="../chapter2/01_The_Basics.html">
<i class="fa fa-check"></i> <b>2.1.</b> 基础部分
</a>
</li>
<li class="chapter " data-level="2.2" data-path="chapter2/02_Basic_Operators.html">
<a href="../chapter2/02_Basic_Operators.html">
<i class="fa fa-check"></i> <b>2.2.</b> 基本运算符
</a>
</li>
<li class="chapter " data-level="2.3" data-path="chapter2/03_Strings_and_Characters.html">
<a href="../chapter2/03_Strings_and_Characters.html">
<i class="fa fa-check"></i> <b>2.3.</b> 字符串和字符
</a>
</li>
<li class="chapter " data-level="2.4" data-path="chapter2/04_Collection_Types.html">
<a href="../chapter2/04_Collection_Types.html">
<i class="fa fa-check"></i> <b>2.4.</b> 集合类型
</a>
</li>
<li class="chapter " data-level="2.5" data-path="chapter2/05_Control_Flow.html">
<a href="../chapter2/05_Control_Flow.html">
<i class="fa fa-check"></i> <b>2.5.</b> 控制流
</a>
</li>
<li class="chapter " data-level="2.6" data-path="chapter2/06_Functions.html">
<a href="../chapter2/06_Functions.html">
<i class="fa fa-check"></i> <b>2.6.</b> 函数
</a>
</li>
<li class="chapter " data-level="2.7" data-path="chapter2/07_Closures.html">
<a href="../chapter2/07_Closures.html">
<i class="fa fa-check"></i> <b>2.7.</b> 闭包
</a>
</li>
<li class="chapter " data-level="2.8" data-path="chapter2/08_Enumerations.html">
<a href="../chapter2/08_Enumerations.html">
<i class="fa fa-check"></i> <b>2.8.</b> 枚举
</a>
</li>
<li class="chapter " data-level="2.9" data-path="chapter2/09_Classes_and_Structures.html">
<a href="../chapter2/09_Classes_and_Structures.html">
<i class="fa fa-check"></i> <b>2.9.</b> 类和结构体
</a>
</li>
<li class="chapter " data-level="2.10" data-path="chapter2/10_Properties.html">
<a href="../chapter2/10_Properties.html">
<i class="fa fa-check"></i> <b>2.10.</b> 属性
</a>
</li>
<li class="chapter " data-level="2.11" data-path="chapter2/11_Methods.html">
<a href="../chapter2/11_Methods.html">
<i class="fa fa-check"></i> <b>2.11.</b> 方法
</a>
</li>
<li class="chapter " data-level="2.12" data-path="chapter2/12_Subscripts.html">
<a href="../chapter2/12_Subscripts.html">
<i class="fa fa-check"></i> <b>2.12.</b> 下标脚本
</a>
</li>
<li class="chapter " data-level="2.13" data-path="chapter2/13_Inheritance.html">
<a href="../chapter2/13_Inheritance.html">
<i class="fa fa-check"></i> <b>2.13.</b> 继承
</a>
</li>
<li class="chapter " data-level="2.14" data-path="chapter2/14_Initialization.html">
<a href="../chapter2/14_Initialization.html">
<i class="fa fa-check"></i> <b>2.14.</b> 构造过程
</a>
</li>
<li class="chapter " data-level="2.15" data-path="chapter2/15_Deinitialization.html">
<a href="../chapter2/15_Deinitialization.html">
<i class="fa fa-check"></i> <b>2.15.</b> 析构过程
</a>
</li>
<li class="chapter " data-level="2.16" data-path="chapter2/16_Automatic_Reference_Counting.html">
<a href="../chapter2/16_Automatic_Reference_Counting.html">
<i class="fa fa-check"></i> <b>2.16.</b> 自动引用计数
</a>
</li>
<li class="chapter " data-level="2.17" data-path="chapter2/17_Optional_Chaining.html">
<a href="../chapter2/17_Optional_Chaining.html">
<i class="fa fa-check"></i> <b>2.17.</b> 可选链
</a>
</li>
<li class="chapter " data-level="2.18" data-path="chapter2/18_Type_Casting.html">
<a href="../chapter2/18_Type_Casting.html">
<i class="fa fa-check"></i> <b>2.18.</b> 类型检查
</a>
</li>
<li class="chapter " data-level="2.19" data-path="chapter2/19_Nested_Types.html">
<a href="../chapter2/19_Nested_Types.html">
<i class="fa fa-check"></i> <b>2.19.</b> 嵌套类型
</a>
</li>
<li class="chapter " data-level="2.20" data-path="chapter2/20_Extensions.html">
<a href="../chapter2/20_Extensions.html">
<i class="fa fa-check"></i> <b>2.20.</b> 扩展
</a>
</li>
<li class="chapter " data-level="2.21" data-path="chapter2/21_Protocols.html">
<a href="../chapter2/21_Protocols.html">
<i class="fa fa-check"></i> <b>2.21.</b> 协议
</a>
</li>
<li class="chapter " data-level="2.22" data-path="chapter2/22_Generics.html">
<a href="../chapter2/22_Generics.html">
<i class="fa fa-check"></i> <b>2.22.</b> 泛型
</a>
</li>
<li class="chapter " data-level="2.23" data-path="chapter2/23_Advanced_Operators.html">
<a href="../chapter2/23_Advanced_Operators.html">
<i class="fa fa-check"></i> <b>2.23.</b> 高级操作符
</a>
</li>
</ul>
</li>
<li class="chapter " data-level="3" data-path="chapter3/chapter3.html">
<a href="../chapter3/chapter3.html">
<i class="fa fa-check"></i> <b>3.</b> 语言参考
</a>
<ul class="articles">
<li class="chapter " data-level="3.1" data-path="chapter3/01_About_the_Language_Reference.html">
<a href="../chapter3/01_About_the_Language_Reference.html">
<i class="fa fa-check"></i> <b>3.1.</b> 关于语言参考
</a>
</li>
<li class="chapter " data-level="3.2" data-path="chapter3/02_Lexical_Structure.html">
<a href="../chapter3/02_Lexical_Structure.html">
<i class="fa fa-check"></i> <b>3.2.</b> 词法结构
</a>
</li>
<li class="chapter " data-level="3.3" data-path="chapter3/03_Types.html">
<a href="../chapter3/03_Types.html">
<i class="fa fa-check"></i> <b>3.3.</b> 类型
</a>
</li>
<li class="chapter " data-level="3.4" data-path="chapter3/04_Expressions.html">
<a href="../chapter3/04_Expressions.html">
<i class="fa fa-check"></i> <b>3.4.</b> 表达式
</a>
</li>
<li class="chapter " data-level="3.5" data-path="chapter3/10_Statements.html">
<a href="../chapter3/10_Statements.html">
<i class="fa fa-check"></i> <b>3.5.</b> 语句
</a>
</li>
<li class="chapter " data-level="3.6" data-path="chapter3/05_Declarations.html">
<a href="../chapter3/05_Declarations.html">
<i class="fa fa-check"></i> <b>3.6.</b> 声明
</a>
</li>
<li class="chapter " data-level="3.7" data-path="chapter3/06_Attributes.html">
<a href="../chapter3/06_Attributes.html">
<i class="fa fa-check"></i> <b>3.7.</b> 特性
</a>
</li>
<li class="chapter " data-level="3.8" data-path="chapter3/07_Patterns.html">
<a href="../chapter3/07_Patterns.html">
<i class="fa fa-check"></i> <b>3.8.</b> 模式
</a>
</li>
<li class="chapter " data-level="3.9" data-path="chapter3/08_Generic_Parameters_and_Arguments.html">
<a href="../chapter3/08_Generic_Parameters_and_Arguments.html">
<i class="fa fa-check"></i> <b>3.9.</b> 泛型参数
</a>
</li>
<li class="chapter " data-level="3.10" data-path="chapter3/09_Summary_of_the_Grammar.html">
<a href="../chapter3/09_Summary_of_the_Grammar.html">
<i class="fa fa-check"></i> <b>3.10.</b> 语法总结
</a>
</li>
</ul>
</li>
<li class="divider"></li>
<li>
<a href="http://www.gitbook.io/" target="blank" class="gitbook-link">Generated using GitBook</a>
</li>
<li style="margin-left:15%;"> <iframe src="http://ghbtns.com/github-btn.html?user=numbbbbb&repo=the-swift-programming-language-in-chinese&type=watch&count=true&size=large"
allowtransparency="true" frameborder="0" scrolling="0" width="170" height="30"></iframe></li><li><p style="padding-left:5px;padding-right:5px;">翻译无任何商业目的,仅供内部学习交流使用!</p></li><li><script src="http://s19.cnzz.com/z_stat.php?id=1000480711&web_id=1000480711" language="JavaScript"></script></li>
</ul>
</div>
<div class="book-body">
<div class="body-inner">
<div class="page-wrapper" tabindex="-1">
<div class="book-progress">
<div class="bar">
<div class="inner" style="width: 36.8421052631579%;min-width: 34.21052631578947%;"></div>
</div>
<div class="chapters">
<a href="../index.html" title="Introduction" class="chapter done new-chapter" data-progress="0" style="left: 0%;"></a>
<a href="../chapter1/chapter1.html" title="欢迎使用 Swift" class="chapter done new-chapter" data-progress="1" style="left: 2.6315789473684212%;"></a>
<a href="../chapter1/01_swift.html" title="关于 Swift" class="chapter done " data-progress="1.1" style="left: 5.2631578947368425%;"></a>
<a href="../chapter1/02_a_swift_tour.html" title="Swift 初见" class="chapter done " data-progress="1.2" style="left: 7.894736842105263%;"></a>
<a href="../chapter2/chapter2.html" title="Swift 教程" class="chapter done new-chapter" data-progress="2" style="left: 10.526315789473685%;"></a>
<a href="../chapter2/01_The_Basics.html" title="基础部分" class="chapter done " data-progress="2.1" style="left: 13.157894736842104%;"></a>
<a href="../chapter2/10_Properties.html" title="属性" class="chapter done " data-progress="2.10" style="left: 15.789473684210526%;"></a>
<a href="../chapter2/11_Methods.html" title="方法" class="chapter done " data-progress="2.11" style="left: 18.42105263157895%;"></a>
<a href="../chapter2/12_Subscripts.html" title="下标脚本" class="chapter done " data-progress="2.12" style="left: 21.05263157894737%;"></a>
<a href="../chapter2/13_Inheritance.html" title="继承" class="chapter done " data-progress="2.13" style="left: 23.68421052631579%;"></a>
<a href="../chapter2/14_Initialization.html" title="构造过程" class="chapter done " data-progress="2.14" style="left: 26.31578947368421%;"></a>
<a href="../chapter2/15_Deinitialization.html" title="析构过程" class="chapter done " data-progress="2.15" style="left: 28.94736842105263%;"></a>
<a href="../chapter2/16_Automatic_Reference_Counting.html" title="自动引用计数" class="chapter done " data-progress="2.16" style="left: 31.57894736842105%;"></a>
<a href="../chapter2/17_Optional_Chaining.html" title="可选链" class="chapter done " data-progress="2.17" style="left: 34.21052631578947%;"></a>
<a href="../chapter2/18_Type_Casting.html" title="类型检查" class="chapter done " data-progress="2.18" style="left: 36.8421052631579%;"></a>
<a href="../chapter2/19_Nested_Types.html" title="嵌套类型" class="chapter " data-progress="2.19" style="left: 39.473684210526315%;"></a>
<a href="../chapter2/02_Basic_Operators.html" title="基本运算符" class="chapter " data-progress="2.2" style="left: 42.10526315789474%;"></a>
<a href="../chapter2/20_Extensions.html" title="扩展" class="chapter " data-progress="2.20" style="left: 44.73684210526316%;"></a>
<a href="../chapter2/21_Protocols.html" title="协议" class="chapter " data-progress="2.21" style="left: 47.36842105263158%;"></a>
<a href="../chapter2/22_Generics.html" title="泛型" class="chapter " data-progress="2.22" style="left: 50%;"></a>
<a href="../chapter2/23_Advanced_Operators.html" title="高级操作符" class="chapter " data-progress="2.23" style="left: 52.63157894736842%;"></a>
<a href="../chapter2/03_Strings_and_Characters.html" title="字符串和字符" class="chapter " data-progress="2.3" style="left: 55.26315789473684%;"></a>
<a href="../chapter2/04_Collection_Types.html" title="集合类型" class="chapter " data-progress="2.4" style="left: 57.89473684210526%;"></a>
<a href="../chapter2/05_Control_Flow.html" title="控制流" class="chapter " data-progress="2.5" style="left: 60.526315789473685%;"></a>
<a href="../chapter2/06_Functions.html" title="函数" class="chapter " data-progress="2.6" style="left: 63.1578947368421%;"></a>
<a href="../chapter2/07_Closures.html" title="闭包" class="chapter " data-progress="2.7" style="left: 65.78947368421052%;"></a>
<a href="../chapter2/08_Enumerations.html" title="枚举" class="chapter " data-progress="2.8" style="left: 68.42105263157895%;"></a>
<a href="../chapter2/09_Classes_and_Structures.html" title="类和结构体" class="chapter " data-progress="2.9" style="left: 71.05263157894737%;"></a>
<a href="../chapter3/chapter3.html" title="语言参考" class="chapter new-chapter" data-progress="3" style="left: 73.6842105263158%;"></a>
<a href="../chapter3/01_About_the_Language_Reference.html" title="关于语言参考" class="chapter " data-progress="3.1" style="left: 76.3157894736842%;"></a>
<a href="../chapter3/09_Summary_of_the_Grammar.html" title="语法总结" class="chapter " data-progress="3.10" style="left: 78.94736842105263%;"></a>
<a href="../chapter3/02_Lexical_Structure.html" title="词法结构" class="chapter " data-progress="3.2" style="left: 81.57894736842105%;"></a>
<a href="../chapter3/03_Types.html" title="类型" class="chapter " data-progress="3.3" style="left: 84.21052631578948%;"></a>
<a href="../chapter3/04_Expressions.html" title="表达式" class="chapter " data-progress="3.4" style="left: 86.84210526315789%;"></a>
<a href="../chapter3/10_Statements.html" title="语句" class="chapter " data-progress="3.5" style="left: 89.47368421052632%;"></a>
<a href="../chapter3/05_Declarations.html" title="声明" class="chapter " data-progress="3.6" style="left: 92.10526315789474%;"></a>
<a href="../chapter3/06_Attributes.html" title="特性" class="chapter " data-progress="3.7" style="left: 94.73684210526316%;"></a>
<a href="../chapter3/07_Patterns.html" title="模式" class="chapter " data-progress="3.8" style="left: 97.36842105263158%;"></a>
<a href="../chapter3/08_Generic_Parameters_and_Arguments.html" title="泛型参数" class="chapter " data-progress="3.9" style="left: 100%;"></a>
</div>
</div>
<div class="page-inner">
<section class="normal" id="section-gitbook_123">
<blockquote>
<p>翻译:<a href="https://github.com/xiehurricane" target="_blank">xiehurricane</a><br>校对:<a href="https://github.com/happyming" target="_blank">happyming</a></p>
</blockquote>
<h1 id="-type-casting-">类型转换(Type Casting)</h1>
<hr>
<p>本页包含内容:</p>
<ul>
<li><a href="#defining_a_class_hierarchy_for_type_casting">定义一个类层次作为例子</a></li>
<li><a href="#checking_type">检查类型</a></li>
<li><a href="#downcasting">向下转型(Downcasting)</a></li>
<li><a href="#type_casting_for_any_and_anyobject"><code>Any</code>和<code>AnyObject</code>的类型转换</a></li>
</ul>
<p><em>类型转换</em>是一种检查类实例的方式,并且或者也是让实例作为它的父类或者子类的一种方式。</p>
<p>类型转换在 Swift 中使用<code>is</code> 和 <code>as</code>操作符实现。这两个操作符提供了一种简单达意的方式去检查值的类型或者转换它的类型。</p>
<p>你也可以用来检查一个类是否实现了某个协议,就像在 <a href="Protocols.html#//apple_ref/doc/uid/TP40014097-CH25-XID_363">Checking for Protocol Conformance</a>部分讲述的一样。</p>
<p><a name="defining_a_class_hierarchy_for_type_casting"></a></p>
<h2 id="-">定义一个类层次作为例子</h2>
<p>你可以将它用在类和子类的层次结构上,检查特定类实例的类型并且转换这个类实例的类型成为这个层次结构中的其他类型。这下面的三个代码段定义了一个类层次和一个包含了几个这些类实例的数组,作为类型转换的例子。</p>
<p>第一个代码片段定义了一个新的基础类<code>MediaItem</code>。这个类为任何出现在数字媒体库的媒体项提供基础功能。特别的,它声明了一个 <code>String</code> 类型的 <code>name</code> 属性,和一个<code>init name</code>初始化器。(它假定所有的媒体项都有个名称。)</p>
<pre><code class="lang-swift">class MediaItem {
var name: String
init(name: String) {
self.name = name
}
}
</code></pre>
<p>下一个代码段定义了 <code>MediaItem</code> 的两个子类。第一个子类<code>Movie</code>,在父类(或者说基类)的基础上增加了一个 <code>director</code>(导演) 属性,和相应的初始化器。第二个类在父类的基础上增加了一个 <code>artist</code>(艺术家) 属性,和相应的初始化器:</p>
<pre><code class="lang-swift">class Movie: MediaItem {
var director: String
init(name: String, director: String) {
self.director = director
super.init(name: name)
}
}
class Song: MediaItem {
var artist: String
init(name: String, artist: String) {
self.artist = artist
super.init(name: name)
}
}
</code></pre>
<p>最后一个代码段创建了一个数组常量 <code>library</code>,包含两个<code>Movie</code>实例和三个<code>Song</code>实例。<code>library</code>的类型是在它被初始化时根据它数组中所包含的内容推断来的。Swift 的类型检测器能够演绎出<code>Movie</code> 和 <code>Song</code> 有共同的父类 <code>MediaItem</code> ,所以它推断出 <code>MediaItem[]</code> 类作为 <code>library</code> 的类型。</p>
<pre><code class="lang-swift">let library = [
Movie(name: "Casablanca", director: "Michael Curtiz"),
Song(name: "Blue Suede Shoes", artist: "Elvis Presley"),
Movie(name: "Citizen Kane", director: "Orson Welles"),
Song(name: "The One And Only", artist: "Chesney Hawkes"),
Song(name: "Never Gonna Give You Up", artist: "Rick Astley")
]
// the type of "library" is inferred to be MediaItem[]
</code></pre>
<p>在幕后<code>library</code> 里存储的媒体项依然是 <code>Movie</code> 和 <code>Song</code> 类型的,但是,若你迭代它,取出的实例会是 <code>MediaItem</code> 类型的,而不是 <code>Movie</code> 和 <code>Song</code> 类型的。为了让它们作为它们本来的类型工作,你需要检查它们的类型或者向下转换它们的类型到其它类型,就像下面描述的一样。</p>
<p><a name="checking_type"></a></p>
<h2 id="-checking-type-">检查类型(Checking Type)</h2>
<p>用类型检查操作符(<code>is</code>)来检查一个实例是否属于特定子类型。若实例属于那个子类型,类型检查操作符返回 <code>true</code> ,否则返回 <code>false</code> 。</p>
<p>下面的例子定义了两个变量,<code>movieCount</code> 和 <code>songCount</code>,用来计算数组<code>library</code> 中 <code>Movie</code> 和 <code>Song</code> 类型的实例数量。</p>
<pre><code class="lang-swift">var movieCount = 0
var songCount = 0
for item in library {
if item is Movie {
++movieCount
} else if item is Song {
++songCount
}
}
println("Media library contains \(movieCount) movies and \(songCount) songs")
// prints "Media library contains 2 movies and 3 songs"
</code></pre>
<p>示例迭代了数组 <code>library</code> 中的所有项。每一次, <code>for</code>-<code>in</code> 循环设置
<code>item</code> 为数组中的下一个 <code>MediaItem</code>。</p>
<p>若当前 <code>MediaItem</code> 是一个 <code>Movie</code> 类型的实例, <code>item is Movie</code> 返回
<code>true</code>,相反返回 <code>false</code>。同样的,<code>item is
Song</code>检查item是否为<code>Song</code>类型的实例。在循环结束后,<code>movieCount</code> 和 <code>songCount</code>的值就是被找到属于各自的类型的实例数量。</p>
<p><a name="downcasting"></a></p>
<h2 id="-downcasting-">向下转型(Downcasting)</h2>
<p>某类型的一个常量或变量可能在幕后实际上属于一个子类。你可以相信,上面就是这种情况。你可以尝试向下转到它的子类型,用类型转换操作符(<code>as</code>)</p>
<p>因为向下转型可能会失败,类型转型操作符带有两种不同形式。可选形式( optional form) <code>as?</code> 返回一个你试图下转成的类型的可选值(optional value)。强制形式 <code>as</code> 把试图向下转型和强制解包(force-unwraps)结果作为一个混合动作。</p>
<p>当你不确定向下转型可以成功时,用类型转换的可选形式(<code>as?</code>)。可选形式的类型转换总是返回一个可选值(optional value),并且若下转是不可能的,可选值将是 <code>nil</code> 。这使你能够检查向下转型是否成功。</p>
<p>只有你可以确定向下转型一定会成功时,才使用强制形式。当你试图向下转型为一个不正确的类型时,强制形式的类型转换会触发一个运行时错误。</p>
<p>下面的例子,迭代了<code>library</code>里的每一个 <code>MediaItem</code> ,并打印出适当的描述。要这样做,<code>item</code>需要真正作为<code>Movie</code> 或 <code>Song</code>的类型来使用。不仅仅是作为 <code>MediaItem</code>。为了能够使用<code>Movie</code> 或 <code>Song</code>的 <code>director</code> 或 <code>artist</code>属性,这是必要的。</p>
<p>在这个示例中,数组中的每一个<code>item</code>可能是 <code>Movie</code> 或 <code>Song</code>。 事前你不知道每个<code>item</code>的真实类型,所以这里使用可选形式的类型转换 (<code>as?</code>)去检查循环里的每次下转。</p>
<pre><code class="lang-swift">for item in library {
if let movie = item as? Movie {
println("Movie: '\(movie.name)', dir. \(movie.director)")
} else if let song = item as? Song {
println("Song: '\(song.name)', by \(song.artist)")
}
}
// Movie: 'Casablanca', dir. Michael Curtiz
// Song: 'Blue Suede Shoes', by Elvis Presley
// Movie: 'Citizen Kane', dir. Orson Welles
// Song: 'The One And Only', by Chesney Hawkes
// Song: 'Never Gonna Give You Up', by Rick Astley
</code></pre>
<p>示例首先试图将 <code>item</code> 下转为 <code>Movie</code>。因为 <code>item</code> 是一个 <code>MediaItem</code>
类型的实例,它可能是一个<code>Movie</code>;同样,它可能是一个 <code>Song</code>,或者仅仅是基类
<code>MediaItem</code>。因为不确定,<code>as?</code>形式在试图下转时将返还一个可选值。 <code>item as Movie</code> 的返回值是<code>Movie?</code>类型或 “optional <code>Movie</code>”。</p>
<p>当向下转型为 <code>Movie</code> 应用在两个 <code>Song</code>
实例时将会失败。为了处理这种情况,上面的例子使用了可选绑定(optional binding)来检查可选 <code>Movie</code>真的包含一个值(这个是为了判断下转是否成功。)可选绑定是这样写的“<code>if let movie = item as? Movie</code>”,可以这样解读:</p>
<p>“尝试将 <code>item</code> 转为 <code>Movie</code>类型。若成功,设置一个新的临时常量 <code>movie</code> 来存储返回的可选<code>Movie</code>”</p>
<p>若向下转型成功,然后<code>movie</code>的属性将用于打印一个<code>Movie</code>实例的描述,包括它的导演的名字<code>director</code>。当<code>Song</code>被找到时,一个相近的原理被用来检测 <code>Song</code> 实例和打印它的描述。</p>
<blockquote>
<p>注意:<br>转换没有真的改变实例或它的值。潜在的根本的实例保持不变;只是简单地把它作为它被转换成的类来使用。</p>
</blockquote>
<p><a name="type_casting_for_any_and_anyobject"></a></p>
<h2 id="-any-anyobject-"><code>Any</code>和<code>AnyObject</code>的类型转换</h2>
<p>Swift为不确定类型提供了两种特殊类型别名:</p>
<ul>
<li><code>AnyObject</code>可以代表任何class类型的实例。</li>
<li><code>Any</code>可以表示任何类型,除了方法类型(function types)。</li>
</ul>
<blockquote>
<p>注意:<br>只有当你明确的需要它的行为和功能时才使用<code>Any</code>和<code>AnyObject</code>。在你的代码里使用你期望的明确的类型总是更好的。</p>
</blockquote>
<h3 id="-anyobject-"><code>AnyObject</code>类型</h3>
<p>当需要在工作中使用 Cocoa APIs,它一般接收一个<code>AnyObject[]</code>类型的数组,或者说“一个任何对象类型的数组”。这是因为 Objective-C 没有明确的类型化数组。但是,你常常可以确定包含在仅从你知道的 API 信息提供的这样一个数组中的对象的类型。</p>
<p>在这些情况下,你可以使用强制形式的类型转换(<code>as</code>)来下转在数组中的每一项到比 <code>AnyObject</code> 更明确的类型,不需要可选解析(optional unwrapping)。</p>
<p>下面的示例定义了一个 <code>AnyObject[]</code> 类型的数组并填入三个<code>Movie</code>类型的实例:</p>
<pre><code class="lang-swift">let someObjects: AnyObject[] = [
Movie(name: "2001: A Space Odyssey", director: "Stanley Kubrick"),
Movie(name: "Moon", director: "Duncan Jones"),
Movie(name: "Alien", director: "Ridley Scott")
]
</code></pre>
<p>因为知道这个数组只包含 <code>Movie</code> 实例,你可以直接用(<code>as</code>)下转并解包到不可选的<code>Movie</code>类型(ps:其实就是我们常用的正常类型,这里是为了和可选类型相对比)。</p>
<pre><code class="lang-swift">for object in someObjects {
let movie = object as Movie
println("Movie: '\(movie.name)', dir. \(movie.director)")
}
// Movie: '2001: A Space Odyssey', dir. Stanley Kubrick
// Movie: 'Moon', dir. Duncan Jones
// Movie: 'Alien', dir. Ridley Scott
</code></pre>
<p>为了变为一个更短的形式,下转<code>someObjects</code>数组为<code>Movie[]</code>类型来代替下转每一项方式。</p>
<pre><code class="lang-swift">for movie in someObjects as Movie[] {
println("Movie: '\(movie.name)', dir. \(movie.director)")
}
// Movie: '2001: A Space Odyssey', dir. Stanley Kubrick
// Movie: 'Moon', dir. Duncan Jones
// Movie: 'Alien', dir. Ridley Scott
</code></pre>
<h3 id="-any-"><code>Any</code>类型</h3>
<p>这里有个示例,使用 <code>Any</code> 类型来和混合的不同类型一起工作,包括非<code>class</code>类型。它创建了一个可以存储<code>Any</code>类型的数组 <code>things</code>。</p>
<pre><code class="lang-swift">var things = Any[]()
things.append(0)
things.append(0.0)
things.append(42)
things.append(3.14159)
things.append("hello")
things.append((3.0, 5.0))
things.append(Movie(name: "Ghostbusters", director: "Ivan Reitman"))
</code></pre>
<p><code>things</code> 数组包含两个 <code>Int</code> 值,2个 <code>Double</code> 值,1个 <code>String</code> 值,一个元组 <code>(Double, Double)</code> ,Ivan Reitman 导演的电影“Ghostbusters”。</p>
<p>你可以在 <code>switch</code> <code>cases</code>里用<code>is</code> 和 <code>as</code> 操作符来发觉只知道是 <code>Any</code> 或 <code>AnyObject</code>的常量或变量的类型。 下面的示例迭代 <code>things</code>数组中的每一项的并用<code>switch</code>语句查找每一项的类型。这几种<code>switch</code>语句的情形绑定它们匹配的值到一个规定类型的常量,让它们可以打印它们的值:</p>
<pre><code class="lang-swift">for thing in things {
switch thing {
case 0 as Int:
println("zero as an Int")
case 0 as Double:
println("zero as a Double")
case let someInt as Int:
println("an integer value of \(someInt)")
case let someDouble as Double where someDouble > 0:
println("a positive double value of \(someDouble)")
case is Double:
println("some other double value that I don't want to print")
case let someString as String:
println("a string value of \"\(someString)\"")
case let (x, y) as (Double, Double):
println("an (x, y) point at \(x), \(y)")
case let movie as Movie:
println("a movie called '\(movie.name)', dir. \(movie.director)")
default:
println("something else")
}
}
// zero as an Int
// zero as a Double
// an integer value of 42
// a positive double value of 3.14159
// a string value of "hello"
// an (x, y) point at 3.0, 5.0
// a movie called 'Ghostbusters', dir. Ivan Reitman
</code></pre>
<blockquote>
<p>注意:<br>在一个switch语句的case中使用强制形式的类型转换操作符(as, 而不是 as?)来检查和转换到一个明确的类型。在 switch case 语句的内容中这种检查总是安全的。</p>
</blockquote>
</section>
</div>
</div>
</div>
<a href="../chapter2/17_Optional_Chaining.html" class="navigation navigation-prev " aria-label="Previous page: 可选链"><i class="fa fa-angle-left"></i></a>
<a href="../chapter2/19_Nested_Types.html" class="navigation navigation-next " aria-label="Next page: 嵌套类型"><i class="fa fa-angle-right"></i></a>
</div>
</div>
<script src="../gitbook/jsrepl/jsrepl.js" id="jsrepl-script"></script>
<script src="../gitbook/app.js"></script>
<script src="http://cdn.mathjax.org/mathjax/2.0-latest/MathJax.js?config=TeX-AMS-MML_HTMLorMML"></script>
<script src="../gitbook/plugins/gitbook-plugin-mathjax/plugin.js"></script>
<script>
require(["gitbook"], function(gitbook) {
var config = {};
gitbook.start(config);
});
</script>
<script src="http://yandex.st/highlightjs/8.0/styles/default.min.css"></script><script src="http://yandex.st/highlightjs/8.0/highlight.min.js"></script><script text="javascript">$('pre code').each(function(i, block) {hljs.highlightBlock(block);});</script></body>
</html>