Generics for containers types

Is there a way in rust I can have a fn that accepts some generic in this form

pub fn add_item(&mut self, item: Box<dyn SomeTrait + Send>)
pub fn add_item(&mut self, item: Arc<dyn SomeTrait + Send>)

// what i want is something like this
pub fn add_item(&mut self, item: T<dyn SomeTrait + Send>)

Does something like this work?

trait SomeTrait {}

fn func1<S, T>(_item: T) 
    where
        S: SomeTrait,
        T: AsRef<S> + Send {
    
}

struct X;
impl SomeTrait for X {}

fn main() {
    let a = Arc::new(X{});
    let b = Box::new(X{});
    func1(a);
    func1(b);
}
1 Like

Interesting, I'll give that a go... I'm new to rust but wanted to find all equivalent patterns from my C++ or C# libs and this was a bit of a sticky wicket for me...

Ps thanks for quick response. Out of curiosty how would I add that to a Queue say

pub struct SomeStruct<T> {
    pub items: VecDeque<T<dyn SomeTrait + Send>>
}

Also last missing piece of the puzzle for me is

fn func1<S, T>(item: T)
    where
    S: SomeTrait,
    T: AsRef<S> + Send
{
    // how do i do if Box then access SomeTrait method
    // else if Arc unwrap then access SomeTrait method
}
fn main() {
    let a = Arc::new(X{});
    let b = Box::new(X{});
    func1(a);
    func1(b);
    return;
}

You don't need to "unwrap" an Arc. The AsRef trait ensures that you can make a &S from a &T by calling .as_ref() on it.

Cool so say my SomeTrait had a fn of exec then how would do that like this?

fn func1<S, T>(item: T)
    where
    S: SomeTrait,
    T: AsRef<S> + Send
{
    item.as_ref().exec();
}

Cool, still would love to know what that type would be in a Vec or VecDeque. I'm trying to impliment a thread management system. I have Box working well but there are instances where I would want Arc

e.g.

let a = Arc::new(X{});
let b = Box::new(X{});

// bit of psuedo code
let q : VecDeque<WhatTypeHere that accepts my SomeTrait?>

// because I want to do this
q.push_back(a);
q.push_back(b);

  • You could store a reference in a VecDeque<&dyn SomeTrait>, this will require anything you insert to outlive q
  • You could create an enum store either a Arc or a Box, implement From<Arc<T>>, From<Box<T>>, (possibly other Froms), and make add_item accept a T: Into<MyEnum>.

Enum store sounds interesting I'll have a look at that. Appreciate your time on this.

So for more context I knocked up this and I can pass in Box in my C++ implimentation I use mainly smart pointers sometimes I want to reference some data and sometimes I want to use move symantics depending on use case but I find it useful when doing larger apps to have some sort of manager and a work item that I can inherit from. I think Box and Arc will get me close enough for now

This is what I'm trying to extend

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.