Reputation:
Coming from another language I'm a little confused on how to do some basic stuff in Rust without breaking memory safety.
I'm trying to get references to a pair of elements stored in a Vec. Assume the elements stored in the Vec are large and I do not want to copy them:
struct Element {
key: u64,
data: SomeHugeType
}
In other languages (e.g. C++), I would just create two null pointers or something and loop over the vec like so:
const Element *ele1, *ele2;
ele1 = nullptr;
ele2 = nullptr;
for (auto const &ele : elements) {
if (ele.key == key1) { ele1 = ele; }
if (ele.key == key2) { ele2 = ele; }
if (ele1 != nullptr && ele2 != nullptr) { break; }
}
if (ele1 == nullptr || ele2 == nullptr) { /* uh oh */}
But as far as I know I cannot do this in rust because I cannot have a reference to nothing (nullptr). I cannot borrow an element before I know which element I need to borrow.
How can I initialize some variable ele1
and ele2
before I find the actual elements they should reference in the Vec?
Upvotes: 1
Views: 411
Reputation: 580
To elaborate on Sebastian's answer, you can use None
and Some(element)
instead of nullptr
s in C++:
type SomeHugeType = String;
struct Element {
key: u64,
data: SomeHugeType,
}
fn get_two_elems(elems: &Vec<Element>, key1: u64, key2: u64) -> Option<(&Element, &Element)> {
let (mut elem1, mut elem2) = (None, None);
for elem in elems {
if elem.key == key1 {
elem1 = Some(elem);
} else if elem.key == key2 {
elem2 = Some(elem)
}
if elem1.is_some() && elem2.is_some() {
break;
}
}
if let (Some(elem1), Some(elem2)) = (elem1, elem2) {
Some((elem1, elem2))
} else {
None
}
}
Upvotes: 3
Reputation: 72215
You can have a reference to nothing. It's just the type Option<T&>
Upvotes: 0