In PHP
A list can mix types. [$left, $right] = pair() takes the two values a function returns. count is the length, and the length can change later by appending. Nothing in the type says "this list has 5 elements".
<?php
function pair(int $left, int $right): array
{
return [$left + $right, $left * $right];
}
[$sum, $product] = pair(3, 4);
echo "$sum $product\n";
$point = [10, 2.5, "origin"];
echo $point[0], " ", $point[1], " ", $point[2], "\n";
$zeros = array_fill(0, 5, 0);
echo count($zeros), "\n";
In Rust
A tuple packs mixed types. .0, .1, and .2 read the fields. Destructuring names them. A function returns two values as one tuple, the way [$sum, $product] = pair() does in PHP.
An array [T; N] is one type of element, and the length is part of the type. [0; 5] is five zeros. .len() is the length. for n in &numbers walks the elements.
numbers[10] does not compile. let index = 10; numbers[index] does not compile either: rustc can see the 10.
error: this operation will panic at runtime
--> src/main.rs:3:20
|
3 | println!("{}", numbers[10]);
| ^^^^^^^^^^^ index out of bounds: the length is 5 but the index is 10
|
= note: `#[deny(unconditional_panic)]` on by default
An index the compiler cannot fold still compiles, then panics when it runs. std::hint::black_box(10) is one way to hide a value from rustc's const analysis:
thread 'main' panicked at src/main.rs:4:20:
index out of bounds: the len is 5 but the index is 10
.get(10) returns Option. Here it is None.
A slice is a view of contiguous elements: &[T]. &numbers[1..3] is a two-element borrow of the array (indexes 1 and 2). The next lessons pass &[Option<i32>] the same way. Chapter 3 goes deeper on borrowing. When the length has to change, use Vec. That is the next lesson.
fn pair(left: i32, right: i32) -> (i32, i32) {
(left + right, left * right)
}
fn main() {
let point = (10, 2.5, "origin");
let x0 = point.0;
let y0 = point.1;
let label0 = point.2;
println!("{x0} {y0} {label0}");
let (x, y, label) = point;
println!("{x} {y} {label}");
let (sum, product) = pair(3, 4);
println!("{sum} {product}");
let zeros = [0; 5];
let len = zeros.len();
println!("{len} {zeros:?}");
let numbers = [10, 20, 30, 40, 50];
for n in &numbers {
println!("{n}");
}
let index = 1;
let chosen = numbers[index];
println!("{chosen}");
let missing = numbers.get(10);
println!("{missing:?}");
let mid: &[i32] = &numbers[1..3];
println!("{mid:?}");
}
pair(3, 4) prints 7 and 12. zeros prints 5 [0, 0, 0, 0, 0]. chosen is 20. missing is None. mid is [20, 30].
To see the runtime panic, replace let index = 1; with let index = std::hint::black_box(10); and run it. The index is 10, the length is 5, and the program panics.
Watch for:
numbers[10]is a compile error on a[T; N]. Aletthat rustc can see through is the same error. Hide the value withblack_box(or parse it from args) when you need a real runtime panic..getis the call that returnsNoneinstead of panicking.
Idiomatic Rust: Return
(sum, product)when a function has two results.for n in &numbersto walk an array.&numbers[1..3]for a slice..get(index)when the index comes from outside the program.
Side by side
| PHP | Rust | |
|---|---|---|
| Mixed values | One array | A tuple, read with .0 or destructuring |
| Two return values | return [a, b] and [$a, $b] = f() |
-> (i32, i32) |
| Fixed list | array_fill, length can still change |
[T; N]. [0; 5] |
| Out of range | A warning, then null |
Constant index: compile error. Opaque runtime index: panic. .get is Option |
| Slice of a list | array_slice |
&numbers[1..3] is &[T] |
| Growing list | $a[] = 1 |
Vec, next lesson |
Try it
Open src/main.rs in the Playground. chosen prints 20 and missing prints None. Change index to std::hint::black_box(10) and run it. The program panics: the length is 5 and the index is 10. Put 1 back.
Key takeaways
- A tuple holds mixed types.
.0reads a field, and destructuring names the fields. Two return values are one tuple. [T; N]fixes the length in the type.[0; 5]repeats a value.for n in &numberswalks it.&numbers[1..3]is a slice (&[T]).numbers[10]does not compile. An index rustc cannot precompute panics..getreturnsOption.- A list whose length changes is a
Vec.
What's next: Vec and HashMap