How to add a trait value into HashMap?


#1

Meet this probleam. I tried Box<trait_name>. but i cant.

pub Trait MyTrait {
  fn myfunc()
}

pub struct App {
  pub services:  HashMap<String, Box<MyTrait>>,
}

// compiler failed
// my trait is object safe, where is wrong?

src/app/app.rs:39:9: 41:10 help: run `rustc --explain E0063` to see a detailed explanation
src/app/app.rs:47:20: 47:37 error: no associated item named `both` found for type `persistent::Read<app::app::App>` in the current scope
src/app/app.rs:47         chain.link(Read::<App>::both(self));
                                     ^~~~~~~~~~~~~~~~~
src/app/app.rs:47:20: 47:37 note: the method `both` exists but the following trait bounds were not satisfied: `app::app::App : std::marker::Send`, `app::app::App : std::marker::Sync`
src/app/app.rs:64:24: 64:27 error: no method named `get` found for type `&Self` in the current scope
src/app/app.rs:64         let app = self.get::<Read<App>>().unwrap();
                                         ^~~
src/app/app.rs:64:24: 64:27 help: items from traits can only be used if the trait is implemented and in scope; the following traits define an item `get`, perhaps you need to implement one of them:
src/app/app.rs:64:24: 64:27 help: candidate #1: `std::collections::hash::Recover`
src/app/app.rs:64:24: 64:27 help: candidate #2: `core::slice::SliceExt`
src/app/app.rs:64:24: 64:27 help: candidate #3: `collections::btree::Recover`
src/app/app.rs:64:24: 64:27 help: candidate #4: `plugin::Pluggable`
error: aborting due to 3 previous errors



// Complete code

impl Key for App { type Value = App; }

pub struct App {
    pub services: HashMap<String, Box<ServiceContract>>,
    pub shared_context: SharedContext,
}

impl App {
    pub fn new(env: &Env) -> App {
        let sct = SharedContext::new(&env);

        App {
            shared_context: sct,
        }
    }

    pub fn start(mut self) -> Chain {
        let router = App::router();
        let mut chain = Chain::new(router);
        chain.link(Read::<App>::both(self));

        chain
    }
}


#2

I want to make App as a glob shared object in iron request lifecycle. This is code’s meaning.


#3

I am not sure if i understand your problem. But this is what i managed to write:

use std::collections::HashMap;
pub trait MyTrait {
  fn myfunc(&self);
}
struct Foo;
struct Bar;

impl MyTrait for Foo{
    fn myfunc(&self){
    }
}

impl MyTrait for Bar{
    fn myfunc(&self){
    }
}

pub struct App {
  pub services:  HashMap<String, Box<MyTrait>>,
}

fn main(){
    let mut a = App {services : HashMap::new()};
    a.services.insert("abhi".to_string(), Box::new(Bar));
    a.services.insert("rust".to_string(), Box::new(Foo));
}

#4

Thanks… yes, the issue is the MyTrait dont impl send &


#5

Thanks… yes, the issue is the MyTrait not impl Send & Sync trait.


#6

You can write something like this:

struct App {
  pub services: HashMap<String, Box<MyTrait + Send + Sync>>,
}

#7

:blush:Yes, it is, thanks your help