Bounds check
- Rust course
- Expert
- Lesson 17/46
- 4 min
Learn bounds checks and how to avoid them.
Bounds checks
Every v[i] access includes a bounds check; it's what prevents undefined behaviour in favour of a panic. Its cost is usually too small to measure, and the compiler removes the check when it can prove the index is in bounds. Ways to make the proof easier:
// 1) use an iterator: no check
for x in v.iter() { .. }
// 2) walk two slices together with zip
a.iter().zip(b).map(|(x, y)| x * y).sum::<f64>()
// 3) validate the length up front: the checks in the loop go away
assert_eq!(a.len(), b.len());
for i in 0..a.len() { t += a[i] * b[i]; }Hoisting the check with an assert
A single check before the loop can replace the n checks inside it: from i < a.len() and a.len() == b.len() the compiler infers that b[i] is safe too. It's also a good way to document the function's contract:
fn nokta(a: &[f64], b: &[f64]) -> f64 {
assert_eq!(a.len(), b.len(), "uzunluklar farklı");
a.iter().zip(b).map(|(x, y)| x * y).sum()
}Practice Dot product
Write the nokta function above. Print the result of nokta(&[1.0, 2.0], &[3.0, 4.0]).
Starter code
fn main() {
// buraya yaz
}Sample solution
fn nokta(a: &[f64], b: &[f64]) -> f64 {
assert_eq!(a.len(), b.len(), "uzunluklar farklı");
a.iter().zip(b).map(|(x, y)| x * y).sum()
}
fn main() {
println!("{}", nokta(&[1.0, 2.0], &[3.0, 4.0]));
}Expected output
11
Questions and answers
Review the lesson questions together with their answers. To test yourself, solve the lesson interactively.
1 When is <code>get_unchecked</code> legitimate?
- When a profile shows the check matters and the index's validity is proven another way Correct answer
- Always
- Never
- In debug builds
Explanation: Safe options (iterators, zip, assert) should be tried first; unsafe is the last resort.
2 Walk together
a.iter().____(b).map(|(x, y)| x * y).sum::<f64>()
a.iter().zip(b).map(|(x, y)| x * y).sum::<f64>()
Explanation: zip pairs two iterators and needs no index checks.
3 Access and bounds check
| Term | Meaning |
|---|---|
v[i] |
Checked, panics |
v.get(i) |
Checked, Option |
v.iter() |
No check |
get_unchecked(i) |
unsafe, no check |