I would like to return an element of a vector:
struct EntryOne {
pub name: String,
pub value: Option<String>,
}
struct TestVec {}
impl TestVec {
pub fn new() -> TestVec {
TestVec {}
}
pub fn findAll(&self) -> Vec<EntryOne> {
let mut ret = Vec::new();
ret.push(EntryOne {
name: "foo".to_string(),
value: Some("FooVal".to_string()),
});
ret.push(EntryOne {
name: "foo2".to_string(),
value: Some("FooVal2".to_string()),
});
ret.push(EntryOne {
name: "foo3".to_string(),
value: None,
});
ret.push(EntryOne {
name: "foo4".to_string(),
value: Some("FooVal4".to_string()),
});
ret
}
pub fn findOne(&self) -> Option<EntryOne> {
let mut list = &self.findAll();
if list.len() > 0 {
println!("{} elements found", list.len());
list.first()
} else {
None
}
}
}
fn main() {
let test = TestVec::new();
test.findAll();
test.findOne();
}
(playground)
I always get this error:
error[E0308]: mismatched types
--> src/main.rs:40:13
|
35 | pub fn findOne(&self) -> Option<EntryOne> {
| ---------------- expected `std::option::Option<EntryOne>` because of return type
...
40 | list.first()
| ^^^^^^^^^^^^ expected struct `EntryOne`, found &EntryOne
|
= note: expected type `std::option::Option<EntryOne>`
found type `std::option::Option<&EntryOne>`
How do I return an element?
The source code to access vector elements using the get () function is given below. The given program is compiled and executed successfully. // Rust program to access vector elements // using get () function fn value (n: Option <& char >) { match n { Some (n) => print! ( " {} " ,n), None => println!
This article will introduce how to return a vector from a function efficiently in C++. Use the vector<T> func() Notation to Return Vector From a Function. The return by value is the preferred method if we return a vector variable declared in the function. The efficiency of this method comes from its move-semantics.
That means that the vector containing the values must outlive the return value, otherwise the reference would point to undefined memory. If you cannot change the vector, then you will need to make a copy of your data structure.
Arrays and vectors being one of the first few data structures that new programmers learn, it is no surprise that Rust too has a solid support for them. But as we saw, Rust's safety guarantees do not allow programmers to abuse these fundamental data types.
Look at the signature for Vec::first
:
fn first(&self) -> Option<&T>
Given a reference to a vector, it will return a reference to the first item if there is one, and None
otherwise. That means that the vector containing the values must outlive the return value, otherwise the reference would point to undefined memory.
There are two main avenues:
If you cannot change the vector, then you will need to make a copy of your data structure. The easiest way to do this is to annotate the structure with #[derive(Clone)]
. Then you can call Option::cloned
on the result of first
.
If you can change the vector, then you can remove the first value from it and return it. There are many ways of doing this, but the shortest code-wise is to use the drain
iterator.
#[derive(Debug, Clone)]
struct EntryOne {
name: String,
value: Option<String>,
}
fn find_all() -> Vec<EntryOne> {
vec![
EntryOne {
name: "foo".to_string(),
value: Some("FooVal".to_string()),
},
EntryOne {
name: "foo2".to_string(),
value: Some("FooVal2".to_string()),
},
EntryOne {
name: "foo3".to_string(),
value: None,
},
EntryOne {
name: "foo4".to_string(),
value: Some("FooVal4".to_string()),
},
]
}
fn find_one_by_clone() -> Option<EntryOne> {
find_all().first().cloned()
}
fn find_one_by_drain() -> Option<EntryOne> {
let mut all = find_all();
let mut i = all.drain(0..1);
i.next()
}
fn main() {
println!("{:?}", find_one_by_clone());
println!("{:?}", find_one_by_drain());
}
Additional changes:
TestVec
if there's no state; just make functions.snake_case
for method and variable names.vec!
to construct a vector when providing all the elements.Debug
so you can print the value.If you wanted to always get the last element, you can use pop
:
fn find_one_by_pop() -> Option<EntryOne> {
find_all().pop()
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With