Rust private function throws error when trying to return tuple of values

70 views Asked by At

I have a function I am attempting to return a tuple of values from:

fn get_two_bytes(data: &[u8]) -> (Vec<(u8, u8)>, BTreeSet<(u8, u8)>) {
    let two_byte_vec = data
        .chunks(2)
        .map(|x| (x[0], x[1]))
        .collect::<Vec<_>>();

    let mut two_byte_set : BTreeSet<&(u8, u8)> = BTreeSet::new();
    for n in &two_byte_vec {
        two_byte_set.insert(n);
    }

    return (two_byte_vec, two_byte_set);
}

This error is generated:

error[E0308]: mismatched types
  --> src/lib.rs:13:27
   |
13 |     return (two_byte_vec, two_byte_set);
   |                           ^^^^^^^^^^^^ expected tuple, found `&(u8, u8)`
   |
   = note: expected struct `BTreeSet<(u8, u8)>`
              found struct `BTreeSet<&(u8, u8)>`

I don't want to return &two_byte_set obviously - I want to transfer ownership out of the function. How do I get these two variables to return properly?

2

There are 2 answers

3
Ivan C On BEST ANSWER

The error message here is misleading.

It's talking about the type that BTreeMap holds, which is &(u8, u8) rather than (u8, u8) you promise Int the function signature. Since u8 is Copy, tuple (u8, u8) is also Copy, which means you can just deref n before inserting into the map and remove the type annotation from two_byte_set.

use std::collections::BTreeSet;

fn get_two_bytes(data: &[u8]) -> (Vec<(u8, u8)>, BTreeSet<(u8, u8)>) {
    let two_byte_vec = data.chunks(2).map(|x| (x[0], x[1])).collect::<Vec<_>>();

    let mut two_byte_set = BTreeSet::new();
    for &n in &two_byte_vec {
        two_byte_set.insert(n);
    }

    (two_byte_vec, two_byte_set);
}
0
Silvio Mayolo On

Since you borrow the vector to iterate over in your for loop, the type of n in that loop is &(u8, u8). Fortunately, tuples of u8 can be cloned, so simply clone them into your set.

let mut two_byte_set : BTreeSet<(u8, u8)> = BTreeSet::new();
for n in &two_byte_vec {
    two_byte_set.insert(n.to_owned());
}