1
- <!--
2
- 要翻译的文件:https://github.com/SwiftGGTeam/the-swift-programming-language-in-chinese/blob/swift-6-beta-translation/swift-6-beta.docc/LanguageGuide/TypeCasting.md
3
- Swift 文档源文件地址:https://docs.swift.org/swift-book/documentation/the-swift-programming-language/typecasting
4
- 翻译估计用时:⭐️⭐️⭐️⭐️
5
- -->
6
-
7
- # Type Casting
1
+ # 类型转换
8
2
9
- Determine a value's runtime type and give it more specific type information.
3
+ 确定一个值的运行时类型,并为其提供更具体的类型信息。
10
4
11
- * Type casting* is a way to check the type of an instance,
12
- or to treat that instance as a different
13
- superclass or subclass from somewhere else in its own class hierarchy.
5
+ * 类型转换* 是一种检查实例类型,或将该实例视为其类层次结构中不同父类或子类的方法。
14
6
15
- Type casting in Swift is implemented with the ` is ` and ` as ` operators.
16
- These two operators provide a simple and expressive way
17
- to check the type of a value or cast a value to a different type.
7
+ Swift 中的类型转换是通过 ` is ` 和 ` as ` 操作符实现的。这两个操作符为值的类型检查或类型转换提供了一种简单而富有表现力的方法。
18
8
19
- You can also use type casting to check whether a type conforms to a protocol,
20
- as described in < doc:Protocols#Checking-for-Protocol-Conformance > .
9
+ 你还可以使用类型转换来检查类型是否遵循协议,
10
+ 如 < doc:Protocols#Checking-for-Protocol-Conformance > 中所述。
21
11
22
- ## Defining a Class Hierarchy for Type Casting
12
+ ## 为类型转换定义类层次结构
23
13
24
- You can use type casting with a hierarchy of classes and subclasses
25
- to check the type of a particular class instance
26
- and to cast that instance to another class within the same hierarchy.
27
- The three code snippets below define a hierarchy of classes
28
- and an array containing instances of those classes,
29
- for use in an example of type casting.
14
+ 你可以使用类型转换在类和子类的层次结构中检查某个类实例的类型,并将该实例转换为同一层次结构中的另一个类。下面的三个代码片段定义了一个类层次结构和一个包含这些类的实例的数组,作为类型转换示例。
30
15
31
- The first snippet defines a new base class called ` MediaItem ` .
32
- This class provides basic functionality for any kind of item that appears
33
- in a digital media library.
34
- Specifically, it declares a ` name ` property of type ` String ` ,
35
- and an ` init(name:) ` initializer.
36
- (It's assumed that all media items, including all movies and songs, will have a name.)
16
+ 第一个代码片段定义了一个新的名为 ` MediaItem ` 的基类。该类为数字媒体库中出现的任何类型项目提供基本功能。具体来说,它声明了一个 ` String ` 类型的 ` name ` 属性和一个 ` init(name:) ` 初始化器。(假设所有媒体项目,包括所有电影和歌曲,都有一个名称。)
37
17
38
18
``` swift
39
19
class MediaItem {
@@ -57,12 +37,7 @@ class MediaItem {
57
37
```
58
38
-->
59
39
60
- The next snippet defines two subclasses of ` MediaItem ` .
61
- The first subclass, ` Movie ` , encapsulates additional information about a movie or film.
62
- It adds a ` director ` property on top of the base ` MediaItem ` class,
63
- with a corresponding initializer.
64
- The second subclass, ` Song ` , adds an ` artist ` property and initializer
65
- on top of the base class:
40
+ 下一个代码段定义了 ` MediaItem ` 的两个子类。第一个子类 ` Movie ` 封装了电影的附加信息。它在基础 ` MediaItem ` 类的基础上添加了一个 ` director ` 属性和一个相应的初始化器。第二个子类 ` Song ` 在基类的基础上添加了 ` artist ` 属性和初始化器:
66
41
67
42
``` swift
68
43
class Movie : MediaItem {
@@ -104,13 +79,7 @@ class Song: MediaItem {
104
79
```
105
80
-->
106
81
107
- The final snippet creates a constant array called ` library ` ,
108
- which contains two ` Movie ` instances and three ` Song ` instances.
109
- The type of the ` library ` array is inferred
110
- by initializing it with the contents of an array literal.
111
- Swift's type checker is able to deduce that ` Movie ` and ` Song ` have
112
- a common superclass of ` MediaItem ` ,
113
- and so it infers a type of ` [MediaItem] ` for the ` library ` array:
82
+ 最后一个代码段创建了一个名为 ` library ` 的常量数组,其中包含两个 ` Movie ` 实例和三个 ` Song ` 实例。` library ` 数组的类型是通过使用数组字面值初始化来推断的。Swift 的类型检查程序能够推断出 ` Movie ` 和 ` Song ` 有一个共同的父类 ` MediaItem ` ,从而推断出 library 数组的类型为 ` [MediaItem] ` :
114
83
115
84
``` swift
116
85
let library = [
@@ -120,7 +89,7 @@ let library = [
120
89
Song (name : " The One And Only" , artist : " Chesney Hawkes" ),
121
90
Song (name : " Never Gonna Give You Up" , artist : " Rick Astley" )
122
91
]
123
- // the type of "library" is inferred to be [MediaItem]
92
+ // "library" 的类型被推断为 [MediaItem]
124
93
```
125
94
126
95
<!--
@@ -140,24 +109,13 @@ let library = [
140
109
```
141
110
-->
142
111
143
- The items stored in ` library ` are still ` Movie ` and ` Song ` instances behind the scenes.
144
- However, if you iterate over the contents of this array,
145
- the items you receive back are typed as ` MediaItem ` ,
146
- and not as ` Movie ` or ` Song ` .
147
- In order to work with them as their native type,
148
- you need to * check* their type,
149
- or * downcast* them to a different type,
150
- as described below.
112
+ ` library ` 中存储的项目实际上仍然是 ` Movie ` 和 ` Song ` 实例。但是,如果遍历该数组的内容,返回的项目类型是 ` MediaItem ` ,而不是 ` Movie ` 或 ` Song ` 。为了以原始类型处理它们,你需要* 检查* 它们的类型,或将它们* 向下转型* 为不同的类型,如下文所述。
151
113
152
- ## Checking Type
114
+ ## 检查类型
153
115
154
- Use the * type check operator* (` is ` ) to check
155
- whether an instance is of a certain subclass type.
156
- The type check operator returns ` true ` if the instance is of that subclass type
157
- and ` false ` if it's not.
116
+ 使用* 类型检查操作符* (` is ` ) 来检查实例是否属于某个子类类型。如果实例属于该子类类型,则类型检查操作符返回 ` true ` ;反之则返回 ` false ` 。
158
117
159
- The example below defines two variables, ` movieCount ` and ` songCount ` ,
160
- which count the number of ` Movie ` and ` Song ` instances in the ` library ` array:
118
+ 下面的示例定义了两个变量:` movieCount ` 和 ` songCount ` ,用于计算 ` library ` 数组中 ` Movie ` 和 ` Song ` 实例的数量:
161
119
162
120
``` swift
163
121
var movieCount = 0
@@ -172,7 +130,7 @@ for item in library {
172
130
}
173
131
174
132
print (" Media library contains \( movieCount ) movies and \( songCount ) songs" )
175
- // Prints "Media library contains 2 movies and 3 songs"
133
+ // 打印 "Media library contains 2 movies and 3 songs"
176
134
```
177
135
178
136
<!--
@@ -195,54 +153,23 @@ print("Media library contains \(movieCount) movies and \(songCount) songs")
195
153
```
196
154
-->
197
155
198
- This example iterates through all items in the ` library ` array.
199
- On each pass, the ` for ` -` in ` loop sets the ` item ` constant
200
- to the next ` MediaItem ` in the array.
201
-
202
- ` item is Movie ` returns ` true ` if the current ` MediaItem `
203
- is a ` Movie ` instance and ` false ` if it's not.
204
- Similarly, ` item is Song ` checks whether the item is a ` Song ` instance.
205
- At the end of the ` for ` -` in ` loop, the values of ` movieCount ` and ` songCount `
206
- contain a count of how many ` MediaItem ` instances were found of each type.
207
-
208
- ## Downcasting
209
-
210
- A constant or variable of a certain class type may actually refer to
211
- an instance of a subclass behind the scenes.
212
- Where you believe this is the case,
213
- you can try to * downcast* to the subclass type
214
- with a * type cast operator* (` as? ` or ` as! ` ).
215
-
216
- Because downcasting can fail,
217
- the type cast operator comes in two different forms.
218
- The conditional form, ` as? ` , returns an optional value of the type you are trying to downcast to.
219
- The forced form, ` as! ` , attempts the downcast and force-unwraps the result
220
- as a single compound action.
221
-
222
- Use the conditional form of the type cast operator (` as? ` )
223
- when you aren't sure if the downcast will succeed.
224
- This form of the operator will always return an optional value,
225
- and the value will be ` nil ` if the downcast was not possible.
226
- This enables you to check for a successful downcast.
227
-
228
- Use the forced form of the type cast operator (` as! ` )
229
- only when you are sure that the downcast will always succeed.
230
- This form of the operator will trigger a runtime error
231
- if you try to downcast to an incorrect class type.
232
-
233
- The example below iterates over each ` MediaItem ` in ` library ` ,
234
- and prints an appropriate description for each item.
235
- To do this, it needs to access each item as a true ` Movie ` or ` Song ` ,
236
- and not just as a ` MediaItem ` .
237
- This is necessary in order for it to be able to access
238
- the ` director ` or ` artist ` property of a ` Movie ` or ` Song `
239
- for use in the description.
240
-
241
- In this example, each item in the array might be a ` Movie ` ,
242
- or it might be a ` Song ` .
243
- You don't know in advance which actual class to use for each item,
244
- and so it's appropriate to use the conditional form of the type cast operator (` as? ` )
245
- to check the downcast each time through the loop:
156
+ 此示例遍历 ` library ` 数组中的所有项目。每次遍历时,` for ` -` in ` 循环都会将 ` item ` 常量设置为数组中的下一个 ` MediaItem ` 。
157
+
158
+ 如果当前的 ` MediaItem ` 是 ` Movie ` 实例,` item is Movie ` 返回 ` true ` ;反之则返回 ` false ` 。同理,` item is Song ` 会检查项目是否为 ` Song ` 实例。当 ` for ` -` in ` 循环结束时,` movieCount ` 和 ` songCount ` 的值包含了找到的每种类型的 ` MediaItem ` 实例的数量。
159
+
160
+ ## 向下转型
161
+
162
+ 某个类常量或变量可能实际上指向子类的实例。如果你认为情况确实如此,可以尝试使用* 类型转换操作符* (` as? ` 或 ` as! ` )来* 向下转型* 为子类类型。
163
+
164
+ 由于向下转型可能失败,类型转换操作符有两种不同的形式。条件形式,即 ` as? ` ,会返回一个与你尝试向下转型的类型相同的可选值。强制形式,即 ` as! ` ,会执行尝试向下转型并将结果强制解包的复合操作。
165
+
166
+ 如果不确定向下转型能否成功,请使用类型转换操作符的条件形式(` as? ` )。这种形式的操作符将始终返回一个可选值,如果向下转型不成功,该值将为 ` nil ` 。这样,你就可以检查是否成功进行了向下转型。
167
+
168
+ 只有在确定向下转型一定会成功时,才使用类型转换操作符的强制形式(` as! ` )。如果尝试向下转型到一个不正确的类类型,这种形式的操作符会触发运行时错误。
169
+
170
+ 下面的示例遍历 ` library ` 中的每个 ` MediaItem ` ,并为每个项目打印适当的描述。为此,它需要将每个项目作为真正的 ` Movie ` 或 ` Song ` 来访问,而不仅仅是作为一个 ` MediaItem ` 。因为只有这样才能访问 ` Movie ` 的 ` director ` 或 ` Song ` 的 ` artist ` 属性,并在描述中使用。
171
+
172
+ 在本例中,数组中的每个项目可能是一部 ` Movie ` ,也可能是一首 ` Song ` 。我们事先并不知道哪个项目是什么类型,因此这里较为恰当的做法,是使用类型转换操作符的条件形式(` as? ` )在循环中进行向下转型。
246
173
247
174
``` swift
248
175
for item in library {
@@ -280,36 +207,15 @@ for item in library {
280
207
```
281
208
-->
282
209
283
- The example starts by trying to downcast the current ` item ` as a ` Movie ` .
284
- Because ` item ` is a ` MediaItem ` instance, it's possible that it * might* be a ` Movie ` ;
285
- equally, it's also possible that it might be a ` Song ` ,
286
- or even just a base ` MediaItem ` .
287
- Because of this uncertainty, the ` as? ` form of the type cast operator returns an * optional* value
288
- when attempting to downcast to a subclass type.
289
- The result of ` item as? Movie ` is of type ` Movie? ` , or “optional ` Movie ` ”.
290
-
291
- Downcasting to ` Movie ` fails when applied to
292
- the ` Song ` instances in the library array.
293
- To cope with this, the example above uses optional binding
294
- to check whether the optional ` Movie ` actually contains a value
295
- (that is, to find out whether the downcast succeeded.)
296
- This optional binding is written “` if let movie = item as? Movie ` ”,
297
- which can be read as:
298
-
299
- “Try to access ` item ` as a ` Movie ` .
300
- If this is successful,
301
- set a new temporary constant called ` movie ` to
302
- the value stored in the returned optional ` Movie ` .”
303
-
304
- If the downcasting succeeds, the properties of ` movie ` are then used
305
- to print a description for that ` Movie ` instance, including the name of its ` director ` .
306
- A similar principle is used to check for ` Song ` instances,
307
- and to print an appropriate description (including ` artist ` name)
308
- whenever a ` Song ` is found in the library.
309
-
310
- > Note: Casting doesn't actually modify the instance or change its values.
311
- > The underlying instance remains the same; it's simply treated and accessed
312
- > as an instance of the type to which it has been cast.
210
+ 该示例首先尝试将当前 ` item ` 向下转型为 ` Movie ` 。由于 ` item ` 是一个 ` MediaItem ` 实例,它有* 可能* 是一部 ` Movie ` ;同样,它也有可能是一首 ` Song ` ,或者只是一个基本的 ` MediaItem ` 。由于这种不确定性,当尝试向下转型到子类类型时,类型转换运算符的 ` as? ` 形式会返回一个* 可选* 值。` item as? Movie ` 的结果是 ` Movie? ` (“可选 ` Movie ` ”)类型。
211
+
212
+ 当应用到库数组中的 ` Song ` 实例时,向下转型为 ` Movie ` 会失败。为了解决这个问题,上面的示例使用了可选绑定来检查可选 ` Movie ` 是否实际包含一个值(即,检查向下转型是否成功。)这里的可选绑定写作“` if let movie = item as? Movie ` ”,可以理解为:
213
+
214
+ “尝试将 ` item ` 作为 ` Movie ` 访问。如果成功,则将名为 ` movie ` 的新临时常量设置为存储在返回的可选 ` Movie ` 中的值。”
215
+
216
+ 如果向下转型成功,` movie ` 的属性将用于打印该 ` Movie ` 实例的说明,包括其导演的姓名。类似的原理也用于检查 ` Song ` 实例,并在从资源库中找到歌曲时打印适当的描述(包括艺术家姓名)。
217
+
218
+ > 注意: 类型转换并不修改实例或更改其值。底层的实例保持不变,它们只是被当作转换后的类型实例来处理和访问。
313
219
314
220
<!--
315
221
TODO: This example should be followed by the same example written with switch,
@@ -323,20 +229,16 @@ whenever a `Song` is found in the library.
323
229
The reference shows the behavior in a contrived example.
324
230
-->
325
231
326
- ## Type Casting for Any and AnyObject
232
+ ## Any 和 AnyObject 的类型转换
327
233
328
- Swift provides two special types for working with nonspecific types:
234
+ Swift 为处理非特定类型提供了两种通用类型:
329
235
330
- - ` Any ` can represent an instance of any type at all, including function types.
331
- - ` AnyObject ` can represent an instance of any class type.
236
+ - ` Any ` 可以表示任何类型的实例,包括函数类型。
237
+ - ` AnyObject ` 可以表示任何类类型的实例。
332
238
333
- Use ` Any ` and ` AnyObject ` only when you explicitly need
334
- the behavior and capabilities they provide.
335
- It's always better to be specific about the types you expect to work with in your code.
239
+ 只有在明确需要它们提供的行为和功能时,才使用 ` Any ` 和 ` AnyObject ` 。在代码中最好明确指定你希望使用的类型。
336
240
337
- Here's an example of using ` Any ` to work with a mix of different types,
338
- including function types and nonclass types.
339
- The example creates an array called ` things ` , which can store values of type ` Any ` :
241
+ 下面是一个使用 ` Any ` 处理不同类型(包括函数类型和非类类型)的示例。该示例创建了一个名为 ` things ` 的数组,可以存储 ` Any ` 类型的值:
340
242
341
243
``` swift
342
244
var things: [Any ] = []
@@ -368,20 +270,10 @@ things.append({ (name: String) -> String in "Hello, \(name)" })
368
270
```
369
271
-->
370
272
371
- The ` things ` array contains
372
- two ` Int ` values, two ` Double ` values, a ` String ` value,
373
- a tuple of type ` (Double, Double) ` ,
374
- the movie “Ghostbusters”,
375
- and a closure expression that takes a ` String ` value
376
- and returns another ` String ` value.
377
-
378
- To discover the specific type of a constant or variable
379
- that's known only to be of type ` Any ` or ` AnyObject ` ,
380
- you can use an ` is ` or ` as ` pattern in a ` switch ` statement's cases.
381
- The example below iterates over the items in the ` things ` array
382
- and queries the type of each item with a ` switch ` statement.
383
- Several of the ` switch ` statement's cases bind their matched value to
384
- a constant of the specified type to enable its value to be printed:
273
+ ` things ` 数组包含两个 ` Int ` 值、两个 ` Double ` 值、一个 ` String ` 值、一个类型为 ` (Double, Double) ` 的元组、电影 “捉鬼敢死队”,以及一个接收 ` String ` 值并返回另一个 ` String ` 值的闭包表达式。
274
+
275
+
276
+ 如果常量或变量的已知类型是 ` Any ` 或 ` AnyObject ` ,要确定其具体类型,可以在 ` switch ` 语句的 case 下使用 ` is ` 或 ` as ` 模式。下面的示例遍历了 ` things ` 数组中的项目,并使用 ` switch ` 语句查询了每个项目的类型。该 ` switch ` 语句的一些 case 将其匹配值与指定类型的常量绑定,以便打印其值:
385
277
386
278
``` swift
387
279
for thing in things {
@@ -459,17 +351,12 @@ for thing in things {
459
351
```
460
352
-->
461
353
462
- > Note: The ` Any ` type represents values of any type, including optional types.
463
- > Swift gives you a warning if you use an optional value
464
- > where a value of type ` Any ` is expected.
465
- > If you really do need to use an optional value as an ` Any ` value,
466
- > you can use the ` as ` operator to explicitly cast the optional to ` Any ` ,
467
- > as shown below.
354
+ > 注意: ` Any ` 类型代表任何类型的值,包括可选类型。如果你使用的是可选值,而预期值是 ` Any ` 类型,Swift 会发出警告。如果你您确实需要将可选值用作 ` Any ` 值,可以使用 ` as ` 操作符显式地将可选值转换为 ` Any ` 值,如下所示。
468
355
>
469
356
> ``` swift
470
357
> let optionalNumber: Int ? = 3
471
- > things.append (optionalNumber) // Warning
472
- > things.append (optionalNumber as Any ) // No warning
358
+ > things.append (optionalNumber) // 会警告
359
+ > things.append (optionalNumber as Any ) // 不会警告
473
360
> ```
474
361
475
362
<!--
@@ -528,11 +415,11 @@ for thing in things {
528
415
```
529
416
-->
530
417
531
- > Beta Software:
418
+ > 测试版软件:
532
419
>
533
- > This documentation contains preliminary information about an API or technology in development. This information is subject to change, and software implemented according to this documentation should be tested with final operating system software.
420
+ > 本文档包含有关正在开发的 API 或技术的初步信息。此信息可能会发生变化,根据本文档实施的软件应使用最终操作系统软件进行测试。
534
421
>
535
- > Learn more about using [ Apple's beta software ] ( https://developer.apple.com/support/beta-software/ ) .
422
+ > 了解有关使用 [ Apple 测试版软件 ] ( https://developer.apple.com/support/beta-software/ ) 的更多信息。
536
423
537
424
<!--
538
425
This source file is part of the Swift.org open source project
0 commit comments