---
Title: Rust and Swift (vii)
Subtitle: Pattern matching and the value of expression blocks.
Category: Tech
Tags: [software development, listicles, rust, swift, rust-and-swift]
Date: 2015-09-19 15:00
Modified: 2015-09-20 13:42
eries:
Title: Rust and Swift
Part: 7
...
I am reading through the Swift book, and comparing it to Rust, which I have also been learning over the past month. As with the other posts in this series, these are off-the-cuff impressions, which may be inaccurate in various ways. I'd be happy to hear feedback! Note, too, that my preferences are just that: preferences. Your tastes may differ from mine. [(See all parts in the series.)][series]
[series]: /rust-and-swift.html
---
- Both Rust and Swift have *pattern-matching*, and with what appears to be fairly similar basic behavior. (I touched on this briefly in my [first post in the series].) In Rust this goes under the `match` construct, with matches specified like ` => `, optionally with guards specified with `if` expressions. In Swift, patterns are matched using the `switch` construct, with matches specified like `case : `, optionally with guards specified with `where` expressions. (`where` is also used in Rust, but for generic constraints, not pattern match guards.)
- Both languages allow you to bind names to a matched pattern: Swift with `case let ` and Rust simply by using the name in a normal destructuring expression as part of the match definition.
**Edit:** that's not *quite* right. In Rust, you use the `@` operator with the variable name you want to bind in the match.
**Edit the second:** I was mixed up, because Rust actually has *both* of those options. You can either match directly, e.g. when getting the value of an `Option` type: `Some(value)` as the pattern will bind `value`. But if you need to bind a specific part of more complicated data structure, the `@` operator is present to let you do it in a fairly straightforward way.
- Both languages allow for the use of `_` as a "wildcard" in match definitions. Since match definitions in Rust use the patterns directly, the equivalent of Swift's C-like `default` is simply a wildcard match pattern (`_ => <-expression|statement>`).
- One significant difference: like its `if` blocks, Rust's `match` blocks are expressions, so they can be assigned. I.e., you can write this:
```rust
let test = 5u32;
let description = match test {
0..10 => "less than ten",
_ => "greater than ten",
}
println!("{?:}"); // "less than ten"
```
Swift doesn't let you do this; the same thing there would be written like this:
```swift
let test: UInt32 = 5
var description: String
switch test {
case 0..<10:
description = "less than ten"
default:
description = "greater than ten"
}
println("\(description)")
```
- Both languages have `break` statements, but in Rust they're only used in loop constructs, while Swift (like C) uses them to escape `case`s as well. The Swift book gives an example of one place they're necessary in a `switch`: to match a case and do nothing there (e.g. `default: break`). In Rust, you would simply supply an empty block for that scenario (e.g. `_ => {}`).
- Correctly, both languages force you to match exhaustively on relevant patterns. If you're matching an enumerated type, for example, you must handle every enumerated value. You can of course do this with wildcard patterns or with Swift's `default`, but the good thing is that both languages will refuse even to compile if a given pattern isn't matched.
- Swift's default behavior around its `switch` statements is sane: it does *not* automatically fall through into the next statement. It does let you do this, without checking the condition on the next statement (as in C), using the `fallthrough` keyword. Rust, by contrast, simply doesn't allow this at all.
- Both languages supply named control statements (loops, etc.), with slightly different syntax for naming them. Rust's, curiously, shares its syntax with lifetime definitions---more on those in a future post.
- I don't believe Rust has anything quite like Swift's `guard`s, which allow you to leave normal or expected control flow in the main body of a block, with a secondary block for cases where the `guard` isn't matched. This isn't a huge deal, but it does fit as a nice convenience into the typical `if let` pattern in Swift. Basically, it just lets you elide an empty `if` block and supply only the `else` block.
**Edit:** a friend [points out] that Swift `guard`s also require you to exit the current scope, so it's unambiguous what you're doing if you use them.
[first post in the series]: /2015/rust-and-swift-i.html
[points out]: https://alpha.app.net/jws/post/64804111
---
- [**Previous:** Collection types and the difference between syntax and semantics.][6]
- [**Next:** Functions, closures, and an awful lot of Swift syntax.][8]
[6]: http://v4.chriskrycho.com/2015/rust-and-swift-vi.html
[8]: http://v4.chriskrycho.com/2015/rust-and-swift-viii.html