I want to check my understanding of how Swift and Rust handle function parameters.
From what I’ve seen, Swift has two main parameter modes:
- Pass by value, immutable:
f(x: T)
and - Pass by reference, mutable:
f(x: inout T)
.
And, if I recall, Rust has three:
- Move:
f(x: T)
, - Immutable borrow:
f(x: &T)
, and - Mutable borrow:
f(x: &mut T)
.
My thinking is that Swift's function signatures map to Rust's borrowing semantics:
- Swift's
f(x: T)
behaves like Rust'sf(x: &T)
, - Swift's
f(x: inout T)
behaves like Rust'sf(x: &mut T)
, and - Rust's
f(x: T)
(move) has no Swift equivalent.
The first bullet point is, I assume, the most contentious. In Swift, for most types, f(x: T)
passes by value. However, Swift also uses copy-on-write optimizations. And since their arguments are immutable, it should never actually make a copy, right?
func addOne(x: Int) {
x = x + 1 // Error: Cannot assign to value: 'x' is a 'let' constant
}
Does this analysis seem accurate? Are there edge cases or nuances I'm missing in this comparison between Swift's parameter passing and Rust's ownership/borrowing system?