Initial commit

This commit is contained in:
Zhongwei Li
2025-11-30 08:36:15 +08:00
commit 759b610929
47 changed files with 56475 additions and 0 deletions

View File

@@ -0,0 +1,59 @@
# About the Language Reference
Read the notation that the formal grammar uses.
This part of the book describes the formal grammar of the Swift programming language.
The grammar described here is intended to help you understand the language in more
detail, rather than to allow you to directly implement a parser or compiler.
The Swift language is relatively small, because many common types, functions, and operators
that appear virtually everywhere in Swift code
are actually defined in the Swift standard library. Although these types, functions,
and operators aren't part of the Swift language itself,
they're used extensively in the discussions and code examples in this part of the book.
## How to Read the Grammar
The notation used to describe the formal grammar of the Swift programming language
follows a few conventions:
- An arrow (→) is used to mark grammar productions and can be read as "can consist of."
- Syntactic categories are indicated by *italic* text and appear on both sides
of a grammar production rule.
- Literal words and punctuation are indicated by **`boldface constant width`** text
and appear only on the right-hand side of a grammar production rule.
- Alternative grammar productions are separated by vertical
bars (|). When alternative productions are too long to read easily,
they're broken into multiple grammar production rules on new lines.
- In a few cases, regular font text is used to describe the right-hand side
of a grammar production rule.
- Optional syntactic categories and literals are marked by a trailing
question mark, *?*.
As an example, the grammar of a getter-setter block is defined as follows:
> Grammar of a getter-setter block:
>
> *getter-setter-block* → **`{`** *getter-clause* *setter-clause*_?_ **`}`** | **`{`** *setter-clause* *getter-clause* **`}`**
This definition indicates that a getter-setter block can consist of a getter clause
followed by an optional setter clause, enclosed in braces,
*or* a setter clause followed by a getter clause, enclosed in braces.
The grammar production above is equivalent to the following two productions,
where the alternatives are spelled out explicitly:
> Grammar of a getter-setter block:
>
>
> *getter-setter-block* → **`{`** *getter-clause* *setter-clause*_?_ **`}`** \
> *getter-setter-block* → **`{`** *setter-clause* *getter-clause* **`}`**
<!--
This source file is part of the Swift.org open source project
Copyright (c) 2014 - 2022 Apple Inc. and the Swift project authors
Licensed under Apache License v2.0 with Runtime Library Exception
See https://swift.org/LICENSE.txt for license information
See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
-->

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,372 @@
# Generic Parameters and Arguments
Generalize declarations to abstract away concrete types.
This chapter describes parameters and arguments for generic types, functions, and
initializers. When you declare a generic type, function, subscript, or initializer,
you specify the type parameters that the generic type, function, or initializer
can work with. These type parameters act as placeholders that
are replaced by actual concrete type arguments when an instance of a generic type is
created or a generic function or initializer is called.
For an overview of generics in Swift, see <doc:Generics>.
<!--
NOTE: Generic types are sometimes referred to as :newTerm:`parameterized types`
because they're declared with one or more type parameters.
-->
## Generic Parameter Clause
A *generic parameter clause* specifies the type parameters of a generic
type or function, along with any associated constraints and requirements on those parameters.
A generic parameter clause is enclosed in angle brackets (<>)
and has the following form:
```swift
<<#generic parameter list#>>
```
The *generic parameter list* is a comma-separated list of generic parameters,
each of which has the following form:
```swift
<#type parameter#>: <#constraint#>
```
A generic parameter consists of a *type parameter* followed by
an optional *constraint*. A *type parameter* is simply the name
of a placeholder type
(for example, `T`, `U`, `V`, `Key`, `Value`, and so on).
You have access to the type parameters (and any of their associated types) in the rest of the
type, function, or initializer declaration, including in the signature of the function
or initializer.
The *constraint* specifies that a type parameter inherits
from a specific class or conforms to a protocol or protocol composition.
For example, in the generic function below, the generic parameter `T: Comparable`
indicates that any type argument substituted
for the type parameter `T` must conform to the `Comparable` protocol.
```swift
func simpleMax<T: Comparable>(_ x: T, _ y: T) -> T {
if x < y {
return y
}
return x
}
```
<!--
- test: `generic-params`
```swifttest
-> func simpleMax<T: Comparable>(_ x: T, _ y: T) -> T {
if x < y {
return y
}
return x
}
```
-->
Because `Int` and `Double`, for example, both conform to the `Comparable` protocol,
this function accepts arguments of either type. In contrast with generic types, you don't
specify a generic argument clause when you use a generic function or initializer.
The type arguments are instead inferred from the type of the arguments passed
to the function or initializer.
```swift
simpleMax(17, 42) // T is inferred to be Int
simpleMax(3.14159, 2.71828) // T is inferred to be Double
```
<!--
- test: `generic-params`
```swifttest
>> let r0 =
-> simpleMax(17, 42) // T is inferred to be Int
>> assert(r0 == 42)
>> let r1 =
-> simpleMax(3.14159, 2.71828) // T is inferred to be Double
>> assert(r1 == 3.14159)
```
-->
<!--
Rewrite the above to avoid bare expressions.
Tracking bug is <rdar://problem/35301593>
-->
### Integer Generic Parameters
An *integer generic parameter*
acts as a placeholder for an integer value rather than a type.
It has the following form:
```swift
let <#type parameter#>: <#type>
```
The *type* must be the `Int` type from the Swift standard library,
or a type alias or generic type that resolves to `Int`.
The value you provide for an integer generic parameter
must be either an integer literal
or another integer generic parameter from the enclosing generic context.
For example:
```swift
struct SomeStruct<let x: Int> { }
let a: SomeStruct<2> // OK: integer literal
struct AnotherStruct<let x: Int, T, each U> {
let b: SomeStruct<x> // OK: another integer generic parameter
static let c = 42
let d: SomeStruct<c> // Error: Can't use a constant.
let e: SomeStruct<T> // Error: Can't use a generic type parameter.
let f: SomeStruct<U> // Error: Can't use a parameter pack.
}
```
The value of an integer generic parameter on a type
is accessible as a static constant member of that type,
with the same visibility as the type itself.
The value of an integer generic parameter on a function
is accessible as a constant from within the function.
When used in an expression,
these constants have type `Int`.
```swift
print(a.x) // Prints "4"
```
The value of an integer generic parameter can be inferred
from the types of the arguments you use
when initializing the type or calling the function.
```swift
struct AnotherStruct<let y: Int> {
var s: SomeStruct<y>
}
func someFunction<let z: Int>(s: SomeStruct<z>) {
print(z)
}
let s1 = SomeStruct<12>()
let s2 = AnotherStruct(s: s1) // AnotherStruct.y is inferred to be 12.
someFunction(s: s1) // Prints "12"
```
### Generic Where Clauses
You can specify additional requirements on type parameters and their associated types
by including a generic `where` clause right before the opening curly brace
of a type or function's body.
A generic `where` clause consists of the `where` keyword,
followed by a comma-separated list of one or more *requirements*.
```swift
where <#requirements#>
```
The *requirements* in a generic `where` clause specify that a type parameter inherits from
a class or conforms to a protocol or protocol composition.
Although the generic `where` clause provides syntactic
sugar for expressing simple constraints on type parameters
(for example, `<T: Comparable>` is equivalent to `<T> where T: Comparable` and so on),
you can use it to provide more complex constraints on type parameters
and their associated types. For example,
you can constrain the associated types of type parameters to conform to protocols.
For example, `<S: Sequence> where S.Iterator.Element: Equatable`
specifies that `S` conforms to the `Sequence` protocol
and that the associated type `S.Iterator.Element`
conforms to the `Equatable` protocol.
This constraint ensures that each element of the sequence is equatable.
Integer generic parameters can't have protocol or superclass requirements.
You can also specify the requirement that two types be identical,
using the `==` operator. For example,
`<S1: Sequence, S2: Sequence> where S1.Iterator.Element == S2.Iterator.Element`
expresses the constraints that `S1` and `S2` conform to the `Sequence` protocol
and that the elements of both sequences must be of the same type.
For integer generic parameters,
the `==` operator specifies a requirement for their values.
You can require two integer generic parameters to have the same value,
or you can require a specific integer value for the integer generic parameter.
Any type argument substituted for a type parameter must
meet all the constraints and requirements placed on the type parameter.
A generic `where` clause can appear
as part of a declaration that includes type parameters,
or as part of a declaration
that's nested inside of a declaration that includes type parameters.
The generic `where` clause for a nested declaration
can still refer to the type parameters of the enclosing declaration;
however,
the requirements from that `where` clause
apply only to the declaration where it's written.
If the enclosing declaration also has a `where` clause,
the requirements from both clauses are combined.
In the example below, `startsWithZero()` is available
only if `Element` conforms to both `SomeProtocol` and `Numeric`.
```swift
extension Collection where Element: SomeProtocol {
func startsWithZero() -> Bool where Element: Numeric {
return first == .zero
}
}
```
<!--
- test: `contextual-where-clauses-combine`
```swifttest
>> protocol SomeProtocol { }
>> extension Int: SomeProtocol { }
-> extension Collection where Element: SomeProtocol {
func startsWithZero() -> Bool where Element: Numeric {
return first == .zero
}
}
>> print( [1, 2, 3].startsWithZero() )
<< false
```
-->
<!--
- test: `contextual-where-clause-combine-err`
```swifttest
>> protocol SomeProtocol { }
>> extension Bool: SomeProtocol { }
>> extension Collection where Element: SomeProtocol {
>> func returnTrue() -> Bool where Element == Bool {
>> return true
>> }
>> func returnTrue() -> Bool where Element == Int {
>> return true
>> }
>> }
!$ error: no type for 'Self.Element' can satisfy both 'Self.Element == Int' and 'Self.Element : SomeProtocol'
!! func returnTrue() -> Bool where Element == Int {
!! ^
```
-->
You can overload a generic function or initializer by providing different
constraints, requirements, or both on the type parameters.
When you call an overloaded generic function or initializer,
the compiler uses these constraints to resolve which overloaded function
or initializer to invoke.
For more information about generic `where` clauses and to see an example
of one in a generic function declaration,
see <doc:Generics#Generic-Where-Clauses>.
> Grammar of a generic parameter clause:
>
> *generic-parameter-clause* → **`<`** *generic-parameter-list* **`>`** \
> *generic-parameter-list* → *generic-parameter* | *generic-parameter* **`,`** *generic-parameter-list* \
> *generic-parameter* → *type-name* \
> *generic-parameter* → *type-name* **`:`** *type-identifier* \
> *generic-parameter* → *type-name* **`:`** *protocol-composition-type* \
> *generic-parameter* → **`let`** *type-name* **`:`** *type* \
>
> *generic-where-clause* → **`where`** *requirement-list* \
> *requirement-list* → *requirement* | *requirement* **`,`** *requirement-list* \
> *requirement* → *conformance-requirement* | *same-type-requirement*
>
> *conformance-requirement* → *type-identifier* **`:`** *type-identifier* \
> *conformance-requirement* → *type-identifier* **`:`** *protocol-composition-type* \
> *same-type-requirement* → *type-identifier* **`==`** *type* \
> *same-type-requirement* → *type-identifier* **`==`** *signed-integer-literal*
<!--
NOTE: A conformance requirement can only have one type after the colon,
otherwise, you'd have a syntactic ambiguity
(a comma-separated list types inside of a comma-separated list of requirements).
-->
## Generic Argument Clause
A *generic argument clause* specifies the type arguments of a generic
type.
A generic argument clause is enclosed in angle brackets (<>)
and has the following form:
```swift
<<#generic argument list#>>
```
The *generic argument list* is a comma-separated list of type arguments.
A *type argument* is the name of an actual concrete type that replaces
a corresponding type parameter in the generic parameter clause of a generic type ---
or, for an integer generic parameter,
an integer value that replaces that integer generic parameter.
The result is a specialized version of that generic type.
The example below shows a simplified version of the Swift standard library's
generic dictionary type.
```swift
struct Dictionary<Key: Hashable, Value>: Collection, ExpressibleByDictionaryLiteral {
/* ... */
}
```
<!--
TODO: How are we supposed to wrap code lines like the above?
-->
The specialized version of the generic `Dictionary` type, `Dictionary<String, Int>`
is formed by replacing the generic parameters `Key: Hashable` and `Value`
with the concrete type arguments `String` and `Int`. Each type argument must satisfy
all the constraints of the generic parameter it replaces, including any additional
requirements specified in a generic `where` clause. In the example above,
the `Key` type parameter is constrained to conform to the `Hashable` protocol
and therefore `String` must also conform to the `Hashable` protocol.
You can also replace a type parameter with a type argument that's itself
a specialized version of a generic type (provided it satisfies the appropriate
constraints and requirements). For example, you can replace the type parameter
`Element` in `Array<Element>` with a specialized version of an array, `Array<Int>`,
to form an array whose elements are themselves arrays of integers.
```swift
let arrayOfArrays: Array<Array<Int>> = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
```
<!--
- test: `array-of-arrays`
```swifttest
-> let arrayOfArrays: Array<Array<Int>> = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
```
-->
As mentioned in <doc:GenericParametersAndArguments#Generic-Parameter-Clause>,
you don't use a generic argument clause to specify the type arguments
of a generic function or initializer.
> Grammar of a generic argument clause:
>
> *generic-argument-clause* → **`<`** *generic-argument-list* **`>`** \
> *generic-argument-list* → *generic-argument* | *generic-argument* **`,`** *generic-argument-list* \
> *generic-argument* → *type* | *signed-integer-literal*
<!--
This source file is part of the Swift.org open source project
Copyright (c) 2014 - 2022 Apple Inc. and the Swift project authors
Licensed under Apache License v2.0 with Runtime Library Exception
See https://swift.org/LICENSE.txt for license information
See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
-->

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,500 @@
# Patterns
Match and destructure values.
A *pattern* represents the structure of a single value
or a composite value.
For example, the structure of a tuple `(1, 2)` is a comma-separated list of two
elements. Because patterns represent the structure of a value rather than any
one particular value, you can match them with a variety of values.
For instance, the pattern `(x, y)` matches the tuple `(1, 2)` and any other
two-element tuple. In addition to matching a pattern with a value,
you can extract part or all of a composite value and bind each part
to a constant or variable name.
In Swift, there are two basic kinds of patterns:
those that successfully match any kind of value,
and those that may fail to match a specified value at runtime.
The first kind of pattern is used for destructuring values
in simple variable, constant, and optional bindings.
These include wildcard patterns, identifier patterns,
and any value binding or tuple patterns containing
them. You can specify a type annotation for these patterns
to constrain them to match only values of a certain type.
The second kind of pattern is used for full pattern matching,
where the values you're trying to match against may not be there at runtime.
These include enumeration case patterns, optional patterns, expression patterns,
and type-casting patterns. You use these patterns in a case label of a `switch`
statement, a `catch` clause of a `do` statement,
or in the case condition of an `if`, `while`,
`guard`, or `for`-`in` statement.
> Grammar of a pattern:
>
> *pattern* → *wildcard-pattern* *type-annotation*_?_ \
> *pattern* → *identifier-pattern* *type-annotation*_?_ \
> *pattern* → *value-binding-pattern* \
> *pattern* → *tuple-pattern* *type-annotation*_?_ \
> *pattern* → *enum-case-pattern* \
> *pattern* → *optional-pattern* \
> *pattern* → *type-casting-pattern* \
> *pattern* → *expression-pattern*
## Wildcard Pattern
A *wildcard pattern* matches and ignores any value and consists of an underscore
(`_`). Use a wildcard pattern when you don't care about the values being
matched against. For example, the following code iterates through the closed range `1...3`,
ignoring the current value of the range on each iteration of the loop:
```swift
for _ in 1...3 {
// Do something three times.
}
```
<!--
- test: `wildcard-pattern`
```swifttest
-> for _ in 1...3 {
// Do something three times.
}
```
-->
> Grammar of a wildcard pattern:
>
> *wildcard-pattern* → **`_`**
## Identifier Pattern
An *identifier pattern* matches any value and binds the matched value to a
variable or constant name.
For example, in the following constant declaration, `someValue` is an identifier pattern
that matches the value `42` of type `Int`:
```swift
let someValue = 42
```
<!--
- test: `identifier-pattern`
```swifttest
-> let someValue = 42
```
-->
When the match succeeds, the value `42` is bound (assigned)
to the constant name `someValue`.
When the pattern on the left-hand side of a variable or constant declaration
is an identifier pattern,
the identifier pattern is implicitly a subpattern of a value-binding pattern.
> Grammar of an identifier pattern:
>
> *identifier-pattern* → *identifier*
## Value-Binding Pattern
A *value-binding pattern* binds matched values to variable or constant names.
Value-binding patterns that bind a matched value to the name of a constant
begin with the `let` keyword; those that bind to the name of variable
begin with the `var` keyword.
Identifiers patterns within a value-binding pattern
bind new named variables or constants to their matching values. For example,
you can decompose the elements of a tuple and bind the value of each element to a
corresponding identifier pattern.
```swift
let point = (3, 2)
switch point {
// Bind x and y to the elements of point.
case let (x, y):
print("The point is at (\(x), \(y)).")
}
// Prints "The point is at (3, 2)."
```
<!--
- test: `value-binding-pattern`
```swifttest
-> let point = (3, 2)
-> switch point {
// Bind x and y to the elements of point.
case let (x, y):
print("The point is at (\(x), \(y)).")
}
<- The point is at (3, 2).
```
-->
In the example above, `let` distributes to each identifier pattern in the
tuple pattern `(x, y)`. Because of this behavior, the `switch` cases
`case let (x, y):` and `case (let x, let y):` match the same values.
> Grammar of a value-binding pattern:
>
> *value-binding-pattern* → **`var`** *pattern* | **`let`** *pattern*
<!--
NOTE: We chose to call this "value-binding pattern"
instead of "variable pattern",
because it's a pattern that binds values to either variables or constants,
not a pattern that varies.
"Variable pattern" is ambiguous between those two meanings.
-->
## Tuple Pattern
A *tuple pattern* is a comma-separated list of zero or more patterns, enclosed in
parentheses. Tuple patterns match values of corresponding tuple types.
You can constrain a tuple pattern to match certain kinds of tuple types
by using type annotations.
For example, the tuple pattern `(x, y): (Int, Int)` in the constant declaration
`let (x, y): (Int, Int) = (1, 2)` matches only tuple types in which
both elements are of type `Int`.
When a tuple pattern is used as the pattern in a `for`-`in` statement
or in a variable or constant declaration, it can contain only wildcard patterns,
identifier patterns, optional patterns, or other tuple patterns that contain those.
For example,
the following code isn't valid because the element `0` in the tuple pattern `(x, 0)` is
an expression pattern:
```swift
let points = [(0, 0), (1, 0), (1, 1), (2, 0), (2, 1)]
// This code isn't valid.
for (x, 0) in points {
/* ... */
}
```
<!--
- test: `tuple-pattern`
```swifttest
-> let points = [(0, 0), (1, 0), (1, 1), (2, 0), (2, 1)]
-> // This code isn't valid.
-> for (x, 0) in points {
>> _ = x
/* ... */
}
!$ error: expected pattern
!! for (x, 0) in points {
!! ^
```
-->
The parentheses around a tuple pattern that contains a single element have no effect.
The pattern matches values of that single element's type. For example, the following are
equivalent:
<!--
This test needs to be compiled.
The error message in the REPL is unpredictable as of
Swift version 1.1 (swift-600.0.54.20)
-->
```swift
let a = 2 // a: Int = 2
let (a) = 2 // a: Int = 2
let (a): Int = 2 // a: Int = 2
```
<!--
- test: `single-element-tuple-pattern`
```swifttest
-> let a = 2 // a: Int = 2
-> let (a) = 2 // a: Int = 2
-> let (a): Int = 2 // a: Int = 2
!$ error: invalid redeclaration of 'a'
!! let (a) = 2 // a: Int = 2
!! ^
!$ note: 'a' previously declared here
!! let a = 2 // a: Int = 2
!! ^
!$ error: invalid redeclaration of 'a'
!! let (a): Int = 2 // a: Int = 2
!! ^
!$ note: 'a' previously declared here
!! let a = 2 // a: Int = 2
!! ^
```
-->
> Grammar of a tuple pattern:
>
> *tuple-pattern* → **`(`** *tuple-pattern-element-list*_?_ **`)`** \
> *tuple-pattern-element-list* → *tuple-pattern-element* | *tuple-pattern-element* **`,`** *tuple-pattern-element-list* \
> *tuple-pattern-element* → *pattern* | *identifier* **`:`** *pattern*
## Enumeration Case Pattern
An *enumeration case pattern* matches a case of an existing enumeration type.
Enumeration case patterns appear in `switch` statement
case labels and in the case conditions of `if`, `while`, `guard`, and `for`-`in`
statements.
If the enumeration case you're trying to match has any associated values,
the corresponding enumeration case pattern must specify a tuple pattern that contains
one element for each associated value. For an example that uses a `switch` statement
to match enumeration cases containing associated values,
see <doc:Enumerations#Associated-Values>.
An enumeration case pattern also matches
values of that case wrapped in an optional.
This simplified syntax lets you omit an optional pattern.
Note that,
because `Optional` is implemented as an enumeration,
`.none` and `.some` can appear
in the same switch as the cases of the enumeration type.
```swift
enum SomeEnum { case left, right }
let x: SomeEnum? = .left
switch x {
case .left:
print("Turn left")
case .right:
print("Turn right")
case nil:
print("Keep going straight")
}
// Prints "Turn left".
```
<!--
- test: `enum-pattern-matching-optional`
```swifttest
-> enum SomeEnum { case left, right }
-> let x: SomeEnum? = .left
-> switch x {
case .left:
print("Turn left")
case .right:
print("Turn right")
case nil:
print("Keep going straight")
}
<- Turn left
```
-->
> Grammar of an enumeration case pattern:
>
> *enum-case-pattern* → *type-identifier*_?_ **`.`** *enum-case-name* *tuple-pattern*_?_
## Optional Pattern
An *optional pattern* matches values wrapped in a `some(Wrapped)` case
of an `Optional<Wrapped>` enumeration.
Optional patterns consist of an identifier pattern followed immediately by a question mark
and appear in the same places as enumeration case patterns.
Because optional patterns are syntactic sugar for `Optional`
enumeration case patterns,
the following are equivalent:
```swift
let someOptional: Int? = 42
// Match using an enumeration case pattern.
if case .some(let x) = someOptional {
print(x)
}
// Match using an optional pattern.
if case let x? = someOptional {
print(x)
}
```
<!--
- test: `optional-pattern`
```swifttest
-> let someOptional: Int? = 42
-> // Match using an enumeration case pattern.
-> if case .some(let x) = someOptional {
print(x)
}
<< 42
-> // Match using an optional pattern.
-> if case let x? = someOptional {
print(x)
}
<< 42
```
-->
The optional pattern provides a convenient way to
iterate over an array of optional values in a `for`-`in` statement,
executing the body of the loop only for non-`nil` elements.
```swift
let arrayOfOptionalInts: [Int?] = [nil, 2, 3, nil, 5]
// Match only non-nil values.
for case let number? in arrayOfOptionalInts {
print("Found a \(number)")
}
// Found a 2
// Found a 3
// Found a 5
```
<!--
- test: `optional-pattern-for-in`
```swifttest
-> let arrayOfOptionalInts: [Int?] = [nil, 2, 3, nil, 5]
-> // Match only non-nil values.
-> for case let number? in arrayOfOptionalInts {
print("Found a \(number)")
}
</ Found a 2
</ Found a 3
</ Found a 5
```
-->
> Grammar of an optional pattern:
>
> *optional-pattern* → *identifier-pattern* **`?`**
## Type-Casting Patterns
There are two type-casting patterns, the `is` pattern and the `as` pattern.
The `is` pattern appears only in `switch` statement
case labels. The `is` and `as` patterns have the following form:
```swift
is <#type#>
<#pattern#> as <#type#>
```
The `is` pattern matches a value if the type of that value at runtime is the same as
the type specified in the right-hand side of the `is` pattern --- or a subclass of that type.
The `is` pattern behaves like the `is` operator in that they both perform a type cast
but discard the returned type.
The `as` pattern matches a value if the type of that value at runtime is the same as
the type specified in the right-hand side of the `as` pattern --- or a subclass of that type.
If the match succeeds,
the type of the matched value is cast to the *pattern* specified in the right-hand side
of the `as` pattern.
For an example that uses a `switch` statement
to match values with `is` and `as` patterns,
see <doc:TypeCasting#Type-Casting-for-Any-and-AnyObject>.
> Grammar of a type casting pattern:
>
> *type-casting-pattern* → *is-pattern* | *as-pattern* \
> *is-pattern* → **`is`** *type* \
> *as-pattern* → *pattern* **`as`** *type*
## Expression Pattern
An *expression pattern* represents the value of an expression.
Expression patterns appear only in `switch` statement
case labels.
The expression represented by the expression pattern
is compared with the value of an input expression
using the pattern-matching operator (`~=`) from the Swift standard library.
The matches succeeds
if the `~=` operator returns `true`. By default, the `~=` operator compares
two values of the same type using the `==` operator.
It can also match a value with a range of values,
by checking whether the value is contained within the range,
as the following example shows.
```swift
let point = (1, 2)
switch point {
case (0, 0):
print("(0, 0) is at the origin.")
case (-2...2, -2...2):
print("(\(point.0), \(point.1)) is near the origin.")
default:
print("The point is at (\(point.0), \(point.1)).")
}
// Prints "(1, 2) is near the origin."
```
<!--
- test: `expression-pattern`
```swifttest
-> let point = (1, 2)
-> switch point {
case (0, 0):
print("(0, 0) is at the origin.")
case (-2...2, -2...2):
print("(\(point.0), \(point.1)) is near the origin.")
default:
print("The point is at (\(point.0), \(point.1)).")
}
<- (1, 2) is near the origin.
```
-->
You can overload the `~=` operator to provide custom expression matching behavior.
For example, you can rewrite the above example to compare the `point` expression
with a string representations of points.
```swift
// Overload the ~= operator to match a string with an integer.
func ~= (pattern: String, value: Int) -> Bool {
return pattern == "\(value)"
}
switch point {
case ("0", "0"):
print("(0, 0) is at the origin.")
default:
print("The point is at (\(point.0), \(point.1)).")
}
// Prints "The point is at (1, 2)."
```
<!--
- test: `expression-pattern`
```swifttest
-> // Overload the ~= operator to match a string with an integer.
-> func ~= (pattern: String, value: Int) -> Bool {
return pattern == "\(value)"
}
-> switch point {
case ("0", "0"):
print("(0, 0) is at the origin.")
default:
print("The point is at (\(point.0), \(point.1)).")
}
<- The point is at (1, 2).
```
-->
> Grammar of an expression pattern:
>
> *expression-pattern* → *expression*
<!--
This source file is part of the Swift.org open source project
Copyright (c) 2014 - 2022 Apple Inc. and the Swift project authors
Licensed under Apache License v2.0 with Runtime Library Exception
See https://swift.org/LICENSE.txt for license information
See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
-->

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff