Dusan Djordjevic
Dusan Djordjevic

Reputation: 23

Rust Generic Vector<Vector<T>>

I'm trying to work my way up to rust and I'm stuck on a thing with generic types. Surely you know the example from chapter 10.1 (Generic Data Types). I would like to create a vector that contains both the i32 vector and the char vector. But somehow I can't get it to work.

fn largest<T: PartialOrd + Copy>(list: &[T]) -> T {
    let mut largest = list[0];

    for &item in list.iter() {
        if item > largest {
            largest = item;
        }
    }

    largest
}

fn main() {
    let number_list = vec![34, 50, 25, 100, 65];

    let result = largest(&number_list);
    println!("The largest number is {}", result);

    let char_list = vec!['y', 'm', 'a', 'q'];

    let result = largest(&char_list);
    println!("The largest char is {}", result);
}

I would now like to create a vector

let mut vecvec = Vec<Vec<T>>::new();
vecvec.push(number_list);
vecvec.push(char_list);

unfortunately, it doesn't work. I hope you have advice. Thanks in advance.

Upvotes: 1

Views: 3435

Answers (2)

Masklinn
Masklinn

Reputation: 42592

First, "it doesn't work" is never helpful. It obviously "doesn't work" or you wouldn't be asking for help.

Second, providing the code you're actually working with (on the playground) is much easier than having to guess where the code "which doesn't work" is supposed to go.

Third,

let mut vecvec = Vec<Vec<T>>::new();

T needs to be defined somewhere, and it needs to be something that makes sense.

vecvec.push(number_list);
vecvec.push(char_list);

Vec<T> means all elements of a vec must have the same type. Here you have a Vec<i32> and a Vec<char>. They're not the same type and they can not be reconciled to the same type, so they can't be put in the same vector: Rust does not have ubiquitous type erasure or a "root type" à la Java, you can't just say that you have "a vector of vectors" and leave it at that with the blanks being filled at runtime.

This means you need some sort of indirection to "hide" the divergence, either an enum with a variant for each type of vec you want:

enum Wrapper {
    Numbers(Vec<i32>),
    Chars(Vec<char>)
}

Or a trait through which you can then use a trait object.

Upvotes: 5

Dusan Djordjevic
Dusan Djordjevic

Reputation: 23

everybody, here is the code that has now been created with the help of the answers. In case someone comes up with such an obscure idea ;)

fn largest<T: PartialOrd + Copy>(list: &[T]) -> T {
    let mut largest = list[0];

    for &item in list.iter() {
        if item > largest {
            largest = item;
        }
    }

    largest
}

enum Wrapper {
    Numbers(Vec<i32>),
    Chars(Vec<char>)
}


fn main() {
    let mut number_list = vec![34, 50, 25, 100, 65];

    let result = largest(&number_list);
    println!("The largest number is {}", result);

    let mut char_list = vec!['y', 'm', 'a', 'q'];

    let result = largest(&char_list);
    println!("The largest char is {}", result);

    let mut vec: Vec<Wrapper> = Vec::new();

    vec.push(Wrapper::Numbers(number_list));
    vec.push(Wrapper::Chars(char_list));

    for v in vec.iter() {
        match v {
            Wrapper::Numbers(o) =>{ println!("The largest  is {}", largest(o))},
            Wrapper::Chars(c) => println!("The largest  is {}", largest(c))
        }

    }

}

Upvotes: 1

Related Questions