@@ -26,35 +26,160 @@ public protocol Boolean {
26
26
var boolValue : Bool { get }
27
27
}
28
28
29
- /// A type that can be converted to an associated "raw" type, then
30
- /// converted back to produce an instance equivalent to the original.
29
+ /// A type that can be converted to and from an associated raw value.
30
+ ///
31
+ /// With a `RawRepresentable` type, you can switch back and forth between a
32
+ /// custom type and an associated `RawValue` type without losing the value of
33
+ /// the original `RawRepresentable` type. Using the raw value of a conforming
34
+ /// type streamlines interoperation with Objective-C and legacy APIs and
35
+ /// simplifies conformance to other protocols, such as `Equatable`,
36
+ /// `Comparable`, and `Hashable`.
37
+ ///
38
+ /// The `RawRepresentable` protocol is seen mainly in two categories of types:
39
+ /// enumerations with raw value types and option sets.
40
+ ///
41
+ /// Enumerations with Raw Values
42
+ /// ============================
43
+ ///
44
+ /// For any enumeration with a string, integer, or floating-point raw type, the
45
+ /// Swift compiler automatically adds `RawRepresentable` conformance. When
46
+ /// defining your own custom enumeration, you give it a raw type by specifying
47
+ /// the raw type as the first item in the enumeration's type inheritance list.
48
+ /// You can also use literals to specify values for one or more cases.
49
+ ///
50
+ /// For example, the `Counter` enumeration defined here has an `Int` raw value
51
+ /// type and gives the first case a raw value of `1`:
52
+ ///
53
+ /// enum Counter: Int {
54
+ /// case one = 1, two, three, four, five
55
+ /// }
56
+ ///
57
+ /// You can create a `Counter` instance from an integer value between 1 and 5
58
+ /// by using the `init?(rawValue:)` initializer declared in the
59
+ /// `RawRepresentable` protocol. This initializer is failable because although
60
+ /// every case of the `Counter` type has a corresponding `Int` value, there
61
+ /// are many `Int` values that *don't* correspond to a case of `Counter`.
62
+ ///
63
+ /// for i in 3...6 {
64
+ /// print(Counter(rawValue: i))
65
+ /// }
66
+ /// // Prints "Optional(Counter.three)"
67
+ /// // Prints "Optional(Counter.four)"
68
+ /// // Prints "Optional(Counter.five)"
69
+ /// // Prints "nil"
70
+ ///
71
+ /// Option Sets
72
+ /// ===========
73
+ ///
74
+ /// Option sets all conform to `RawRepresentable` by inheritance using the
75
+ /// `OptionSet` protocol. Whether using an option set or creating your own,
76
+ /// you use the raw value of an option set instance to store the instance's
77
+ /// bitfield. The raw value must therefore be of a type that conforms to the
78
+ /// `BitwiseOperations` protocol, such as `UInt8` or `Int`. For example, the
79
+ /// `Direction` type defines an option set for the four directions you can
80
+ /// move in a game.
81
+ ///
82
+ /// struct Directions: OptionSet {
83
+ /// let rawValue: UInt8
84
+ ///
85
+ /// static let up = Directions(rawValue: 1 << 0)
86
+ /// static let down = Directions(rawValue: 1 << 1)
87
+ /// static let left = Directions(rawValue: 1 << 2)
88
+ /// static let right = Directions(rawValue: 1 << 3)
89
+ /// }
90
+ ///
91
+ /// Unlike enumerations, option sets provide a nonfailable `init(rawValue:)`
92
+ /// initializer to convert from a raw value, because option sets don't have an
93
+ /// enumerated list of all possible cases. Option set values have
94
+ /// a one-to-one correspondence with their associated raw values.
95
+ ///
96
+ /// In the case of the `Directions` option set, an instance can contain zero,
97
+ /// one, or more of the four defined directions. This example declares a
98
+ /// constant with three currently allowed moves. The raw value of the
99
+ /// `allowedMoves` instance is the result of the bitwise `OR` of its three
100
+ /// members' raw values:
101
+ ///
102
+ /// let allowedMoves: Directions = [.up, .down, .left]
103
+ /// print(allowedMoves.rawValue)
104
+ /// // Prints "7"
105
+ ///
106
+ /// Option sets use bitwise operations on their associated raw values to
107
+ /// implement their mathematical set operations. For example, the `contains()`
108
+ /// method on `allowedMoves` performs a bitwise `AND` operation to check
109
+ /// whether the option set contains an element.
110
+ ///
111
+ /// print(allowedMoves.contains(.right))
112
+ /// // Prints "false"
113
+ /// print(allowedMoves.rawValue & Directions.right.rawValue)
114
+ /// // Prints "0"
115
+ ///
116
+ /// - SeeAlso: `OptionSet`, `BitwiseOperations`
31
117
public protocol RawRepresentable {
32
- /// The "raw" type that can be used to represent all values of `Self`.
118
+ /// The raw type that can be used to represent all values of the conforming
119
+ /// type.
33
120
///
34
- /// Every distinct value of `self` has a corresponding unique
35
- /// value of `RawValue`, but `RawValue` may have representations
36
- /// that do not correspond to a value of `Self` .
121
+ /// Every distinct value of the conforming type has a corresponding unique
122
+ /// value of the `RawValue` type , but there may be values of the `RawValue`
123
+ /// type that don't have a corresponding value of the conforming type .
37
124
associatedtype RawValue
38
125
39
- /// Convert from a value of `RawValue`, yielding `nil` iff
40
- /// `rawValue` does not correspond to a value of `Self`.
126
+ /// Creates a new instance with the specified raw value.
127
+ ///
128
+ /// If there is no value of the type that corresponds with the specified raw
129
+ /// value, this initializer returns `nil`. For example:
130
+ ///
131
+ /// enum PaperSize: String {
132
+ /// case A4, A5, Letter, Legal
133
+ /// }
134
+ ///
135
+ /// print(PaperSize(rawValue: "Legal"))
136
+ /// // Prints "Optional("PaperSize.Legal")"
137
+ ///
138
+ /// print(PaperSize(rawValue: "Tabloid"))
139
+ /// // Prints "nil"
140
+ ///
141
+ /// - Parameter rawValue: The raw value to use for the new instance.
41
142
init ? ( rawValue: RawValue )
42
143
43
- /// The corresponding value of the "raw" type.
144
+ /// The corresponding value of the raw type.
145
+ ///
146
+ /// A new instance initialized with `rawValue` will be equivalent to this
147
+ /// instance. For example:
148
+ ///
149
+ /// enum PaperSize: String {
150
+ /// case A4, A5, Letter, Legal
151
+ /// }
44
152
///
45
- /// `Self(rawValue: self.rawValue)!` is equivalent to `self`.
153
+ /// let selectedSize = PaperSize.Letter
154
+ /// print(selectedSize.rawValue)
155
+ /// // Prints "Letter"
156
+ ///
157
+ /// print(selectedSize == PaperSize(rawValue: selectedSize.rawValue)!)
158
+ /// // Prints "true"
46
159
var rawValue : RawValue { get }
47
160
}
48
161
49
- /// Returns `true` iff `lhs.rawValue == rhs.rawValue`.
162
+ /// Returns a Boolean value indicating whether the two operands are equal.
163
+ ///
164
+ /// - Parameters:
165
+ /// - lhs: A raw-representable instance.
166
+ /// - rhs: A second raw-representable instance.
167
+ /// - Returns: `true` if the two operands have equal raw values; otherwise,
168
+ /// `false`.
50
169
@warn_unused_result
51
170
public func == <
52
171
T : RawRepresentable where T. RawValue : Equatable
53
172
> ( lhs: T , rhs: T ) -> Bool {
54
173
return lhs. rawValue == rhs. rawValue
55
174
}
56
175
57
- /// Returns `true` iff `lhs.rawValue != rhs.rawValue`.
176
+ /// Returns a Boolean value indicating whether the two operands are not equal.
177
+ ///
178
+ /// - Parameters:
179
+ /// - lhs: A raw-representable instance.
180
+ /// - rhs: A second raw-representable instance.
181
+ /// - Returns: `true` if the two operands have unequal raw values; otherwise,
182
+ /// `false`.
58
183
@warn_unused_result
59
184
public func != <
60
185
T : RawRepresentable where T. RawValue : Equatable
@@ -64,7 +189,13 @@ public func != <
64
189
65
190
// This overload is needed for ambiguity resolution against the
66
191
// implementation of != for T : Equatable
67
- /// Returns `true` iff `lhs.rawValue != rhs.rawValue`.
192
+ /// Returns a Boolean value indicating whether the two operands are not equal.
193
+ ///
194
+ /// - Parameters:
195
+ /// - lhs: A raw-representable instance.
196
+ /// - rhs: A second raw-representable instance.
197
+ /// - Returns: `true` if the two operands have unequal raw values; otherwise,
198
+ /// `false`.
68
199
@warn_unused_result
69
200
public func != <
70
201
T : Equatable where T : RawRepresentable , T. RawValue : Equatable
@@ -172,10 +303,118 @@ public protocol StringLiteralConvertible
172
303
init ( stringLiteral value: StringLiteralType )
173
304
}
174
305
175
- /// Conforming types can be initialized with array literals.
306
+ /// A type that can be initialized using an array literal.
307
+ ///
308
+ /// An array literal is a simple way of expressing a list of values. Simply
309
+ /// surround a comma-separated list of values, instances, or literals with
310
+ /// square brackets to create an array literal. You can use an array literal
311
+ /// anywhere an instance of an `ArrayLiteralConvertible` type is expected: as
312
+ /// a value assigned to a variable or constant, as a parameter to a method or
313
+ /// initializer, or even as the subject of a nonmutating operation like
314
+ /// `map(_:)` or `filter(_:)`.
315
+ ///
316
+ /// Arrays, sets, and option sets all conform to `ArrayLiteralConvertible`, and
317
+ /// your own custom types can as well. Here's an example of creating a set and
318
+ /// an array using array literals:
319
+ ///
320
+ /// let employeesSet: Set<String> = ["Amir", "Jihye", "Dave", "Alessia", "Dave"]
321
+ /// print(employeesSet)
322
+ /// // Prints "["Amir", "Dave", "Jihye", "Alessia"]"
323
+ ///
324
+ /// let employeesArray: [String] = ["Amir", "Jihye", "Dave", "Alessia", "Dave"]
325
+ /// print(employeesArray)
326
+ /// // Prints "["Amir", "Jihye", "Dave", "Alessia", "Dave"]"
327
+ ///
328
+ /// The `Set` and `Array` types each handle array literals in their own way to
329
+ /// create new instances. In this case, the newly created set drops the
330
+ /// duplicate value ("Dave") and doesn't maintain the order of the array
331
+ /// literal's elements. The new array, on the other hand, matches the order
332
+ /// and number of elements provided.
333
+ ///
334
+ /// - Note: An array literal is not the same as an `Array` instance. You can't
335
+ /// initialize a type that conforms to `ArrayLiteralConvertible` simply by
336
+ /// assigning an existing array.
337
+ ///
338
+ /// let anotherSet: Set = employeesArray
339
+ /// // error: cannot convert value of type '[String]' to specified type 'Set'
340
+ ///
341
+ /// Type Inference of Array Literals
342
+ /// ================================
343
+ ///
344
+ /// Whenever possible, Swift's compiler infers the full intended type of your
345
+ /// array literal. Because `Array` is the default type for an array literal,
346
+ /// without writing any other code, you can declare an array with a particular
347
+ /// element type by providing one or more values.
348
+ ///
349
+ /// In this example, the compiler infers the full type of each array literal.
350
+ ///
351
+ /// let integers = [1, 2, 3]
352
+ /// // 'integers' has type '[Int]'
353
+ ///
354
+ /// let strings = ["a", "b", "c"]
355
+ /// // 'strings' has type '[String]'
356
+ ///
357
+ /// An empty array literal alone doesn't provide enough information for the
358
+ /// compiler to infer the intended type of the `Array` instance. When using an
359
+ /// empty array literal, specify the type of the variable or constant.
360
+ ///
361
+ /// var emptyArray: [Bool] = []
362
+ /// // 'emptyArray' has type '[Bool]'
363
+ ///
364
+ /// Because many functions and initializers fully specify the types of their
365
+ /// parameters, you can often use an array literal with or without elements as
366
+ /// a parameter. For example, the `sum(_:)` function shown here takes an `Int`
367
+ /// array as a parameter:
368
+ ///
369
+ /// func sum(values: [Int]) -> Int {
370
+ /// return values.reduce(0, combine: +)
371
+ /// }
372
+ ///
373
+ /// let sumOfFour = sum([5, 10, 15, 20])
374
+ /// // 'sumOfFour' == 50
375
+ ///
376
+ /// let sumOfNone = sum([])
377
+ /// // 'sumOfNone' == 0
378
+ ///
379
+ /// When you call a function that does not fully specify its parameters' types,
380
+ /// use the type-cast operator (`as`) to specify the type of an array literal.
381
+ /// For example, the `log(name:value:)` function shown here has an
382
+ /// unconstrained generic `value` parameter.
383
+ ///
384
+ /// func log<T>(name name: String, value: T) {
385
+ /// print("\(name): \(value)")
386
+ /// }
387
+ ///
388
+ /// log(name: "Four integers", value: [5, 10, 15, 20])
389
+ /// // Prints "Four integers: [5, 10, 15, 20]"
390
+ ///
391
+ /// log(name: "Zero integers", value: [] as [Int])
392
+ /// // Prints "Zero integers: []"
393
+ ///
394
+ /// Conforming to ArrayLiteralConvertible
395
+ /// =====================================
396
+ ///
397
+ /// Add the capability to be initialized with an array literal to your own
398
+ /// custom types by declaring an `init(arrayLiteral:)` initializer. The
399
+ /// following example shows the array literal initializer for a hypothetical
400
+ /// `OrderedSet` type, which has setlike semantics but maintains the order of
401
+ /// its elements.
402
+ ///
403
+ /// struct OrderedSet<Element: Hashable>: Collection, SetAlgebra {
404
+ /// // implementation details
405
+ /// }
406
+ ///
407
+ /// extension OrderedSet: ArrayLiteralConvertible {
408
+ /// init(arrayLiteral: Element...) {
409
+ /// self.init()
410
+ /// for element in arrayLiteral {
411
+ /// self.append(element)
412
+ /// }
413
+ /// }
414
+ /// }
176
415
public protocol ArrayLiteralConvertible {
177
416
associatedtype Element
178
- /// Create an instance initialized with ` elements` .
417
+ /// Creates an instance initialized with the given elements.
179
418
init ( arrayLiteral elements: Element ... )
180
419
}
181
420
0 commit comments