These are chat archives for rust-lang/rust

11th
Dec 2016
Paul Betts
@paulcbetts
Dec 11 2016 05:51
So
If I want to have a HashMap of String => Vec<u8>
HashMap<String, Vec<u8>>
How does ownership work when I like, add items to the table
boats
@withoutboats
Dec 11 2016 05:53
The table takes ownership of any item you add to it.
Paul Betts
@paulcbetts
Dec 11 2016 05:54
So if I don't want that, the easiest way to fix that is to clone the &Vec<u8>
Right?
boats
@withoutboats
Dec 11 2016 05:55
Yes. Its possible you could have HashMap<String, &[u8]> instead, but that will be more complicated.
Paul Betts
@paulcbetts
Dec 11 2016 05:57
Cool, thanks for the hint. And I take it that HashMap is like Vector, that the contents are heap-allocated?
boats
@withoutboats
Dec 11 2016 05:57
Yep, any collection is going to be heap allocated because its unknown how many elements it will have.
Paul Betts
@paulcbetts
Dec 11 2016 05:57
Ya
Paul Betts
@paulcbetts
Dec 11 2016 06:30
Is there a way to give a hint to match to tell it what type you want as a return type?
    let f : ErrFuture<bool> = match self.data.remove(key) {
      None => failed(Error::new(ErrorKind::Other, "Key not found")),
      _ => done(Ok(true))
    };
Matanel Levi
@matanelevi
Dec 11 2016 10:11
I want to save a member with the type of LinkedList<some struct>.iter()
What it the type of what's returned from iter?
Aleksey Kladov
@matklad
Dec 11 2016 10:15
@matanelevi it is ::std::collections::linked_list::Iter<'a, SomeStruct> where 'a is the lifetime of the list itself.
Matanel Levi
@matanelevi
Dec 11 2016 10:17
'''

'''
struct Exercise {
id: ExerciseId,
desc: &'static str,
handler: ExerciseHandler
}

pub struct ExerciseManager<'a> {
current_exercise: LinkedList::Iter<'a, Exercise>
}
'''

struct Exercise {
    id: ExerciseId,
    desc: &'static str,
    handler: ExerciseHandler
}

pub struct ExerciseManager<'a> {
    current_exercise: LinkedList::Iter<'a, Exercise>
}
Aleksey Kladov
@matklad
Dec 11 2016 10:18
Note that it is linked_list modue and not LinkedList structure.
Matanel Levi
@matanelevi
Dec 11 2016 10:21
@matklad oh.. :) I'm stupid :D
Amm, one more question:
struct Exercise {
    id: ExerciseId,
    desc: &'static str,
    handler: ExerciseHandler
}

pub struct ExerciseManager<'a> {
    current_exercise: linked_list::Iter<'a, Exercise>
}

impl<'a> ExerciseManager<'a> {
    pub fn new() -> &'a ExerciseManager {
        ExerciseManager { current_exercise: EXERCISES.iter() }
    }
}
Where EXERCISES is lazy_static.
I get "expected 1 lifetime parameter" on the pub fn new() -> &'a ExerciseManager
Aleksey Kladov
@matklad
Dec 11 2016 10:23
Nope, you are not stupid at all. Iter should be an associated type of the collection, but currently Rust is unable to express this :(
Matanel Levi
@matanelevi
Dec 11 2016 10:24
@matklad why not?
boats
@withoutboats
Dec 11 2016 10:25
Its because of the lifetime.
You can't have an associated type with a parameter like type Iter<'a>; (yet)
Matanel Levi
@matanelevi
Dec 11 2016 10:26
@withoutboats understood, thanks :)
boats
@withoutboats
Dec 11 2016 10:26
The problem with new is you want ExerciseManager<'a> not &'a ExerciseManager.
Matanel Levi
@matanelevi
Dec 11 2016 10:29
@withoutboats thank you. The difference here is that on &'a ExerciseManager the lifetime is of the reference, and on ExerciseManager<'a> the lifetime is on a static allocated struct?
boats
@withoutboats
Dec 11 2016 10:31
&'a ExerciseManager is a reference to an ExerciseManager, you want to return an ExerciseManager. Exercise manager has the 'a lifetime (its not 'static) because it has the linked lister Iter inside of it (which itself, ultimately, has a reference inside of it)
Matanel Levi
@matanelevi
Dec 11 2016 10:33
@withoutboats Yeah, by static I actually meant stack allocated :D
thanks!
Matanel Levi
@matanelevi
Dec 11 2016 15:01
Hey there, the cargo shouts at me this warning:
warning: field is never used: current_exercise_index, #[warn(dead_code)] on by default
```
pub struct ExerciseManager<'a> {
    exercises: &'a [Exercise],
    current_exercise_index: usize
}

impl<'a> ExerciseManager<'a> {
    pub fn new() -> ExerciseManager<'a> {
        let exercises = EXERCISES.iter();

        ExerciseManager {
            exercises: exercises.as_slice(),
            current_exercise_index: 0,
        }
    }

    pub fn set_exercise(&mut self, id: ExerciseId) -> bool {
        for (i, exercise) in self.exercises.iter().enumerate() {
            if exercise.id == id {
                self.current_exercise_index = i;
                return true;
            }
        }

        false
    }

    pub fn try_answer(&mut self, answer: &Vec<u8>) -> Result<NextExercise> {
        let ref current_exercise = self.exercises[self.current_exercise_index];
        let (exercise_imp, input) = (current_exercise.handler.imp,
                                     current_exercise.handler.input.as_slice());
        // TODO unwrap
        let expected_answer: Vec<u8> = exercise_imp(input).unwrap();

        // TODO: Check answer
        match expected_answer.cmp(answer) {
            Ordering::Equal => {},
            _ => return Err(Error::WrongAnswer),
        }

        self.current_exercise_index += 1;

        if self.current_exercise_index < self.exercises.len()
        {
            let ref next_exercise = self.exercises[self.current_exercise_index];
            Ok(NextExercise::Exercise(next_exercise.id))
        }
        else {
            Ok(NextExercise::AllDone)
        }
    }
}
Somebody knows why?
btw, better-code looking suggestions are welcome
Sergey Noskov
@Albibek
Dec 11 2016 19:13
@matanelevi well, you could do all this using iterators, which is to look way shorter
Matanel Levi
@matanelevi
Dec 11 2016 19:19
@Albibek thats what I did first, but how the set_exercise would look like?
Sergey Noskov
@Albibek
Dec 11 2016 19:21
take_while probably, or position
Matanel Levi
@matanelevi
Dec 11 2016 21:14
@Albibek alright, I will try it
Thanks!