Привет полумертвый форум.
Разгребаю я тут старую ошибку в ZoC и возникла у меня вот такая проблема:
use std::collections::HashMap;
#[derive(Debug)]
struct Object(i32);
trait State {
fn objects(&self) -> &HashMap<i32, Object>;
}
struct FullState {
objects: HashMap<i32, Object>,
}
impl FullState {
fn new() -> FullState {
let mut objects = HashMap::new();
objects.insert(0, Object(100));
objects.insert(1, Object(101));
objects.insert(2, Object(102));
objects.insert(3, Object(103));
FullState {
objects: objects,
}
}
}
impl State for FullState {
fn objects(&self) -> &HashMap<i32, Object> {
&self.objects
}
}
struct TmpPartialState<'a> {
full_state: &'a FullState,
}
impl<'a> TmpPartialState<'a> {
fn new(full_state: &'a FullState) -> TmpPartialState<'a> {
TmpPartialState {
full_state: full_state,
}
}
}
impl<'a> State for TmpPartialState<'a> {
fn objects(&self) -> &HashMap<i32, Object> {
// Хочется, что бы эта функция возвращала не все объекты из полного
// состояния, а, допустим, только с нечетными идентификаторами.
//
// Типажа State можно менять, лишь бы этот метод в итоге был дешевым,
// принимал &self и возвращал что-то, что сразу можно скормить
// в for цикл.
//
self.full_state.objects()
}
}
fn main() {
let full_state = FullState::new();
for (id, object) in full_state.objects() {
println!("{:?} -> {:?}", id, object);
}
println!("---");
let partial_state = TmpPartialState::new(&full_state);
for (id, object) in partial_state.objects() {
println!("{:?} -> {:?}", id, object);
}
}
(https://play.rust-lang.org/?gist=74b077340a3be2665304acf29581477c)
И я пока додумался только до довольно громоздкого решения с реализацией своих собственных итераторов:
use std::collections::hash_map::{self, HashMap};
#[derive(Debug)]
struct Object(i32);
trait State<'a> {
type It: Iterator;
fn objects(&'a self) -> Self::It;
}
struct FullState {
objects: HashMap<i32, Object>,
}
impl FullState {
fn new() -> FullState {
let mut objects = HashMap::new();
objects.insert(0, Object(100));
objects.insert(1, Object(101));
objects.insert(2, Object(102));
objects.insert(3, Object(103));
FullState {
objects: objects,
}
}
}
impl<'a> State<'a> for FullState {
type It = hash_map::Iter<'a, i32, Object>;
fn objects(&'a self) -> Self::It {
self.objects.iter()
}
}
struct TmpPartialState<'a> {
full_state: &'a FullState,
}
impl<'a> TmpPartialState<'a> {
fn new(full_state: &'a FullState) -> TmpPartialState<'a> {
TmpPartialState {
full_state: full_state,
}
}
}
struct StateIter<'a> {
hashmap_iter: hash_map::Iter<'a, i32, Object>,
}
impl<'a> Iterator for StateIter<'a> {
type Item = (&'a i32, &'a Object);
fn next(&mut self) -> Option<Self::Item> {
while let Some(pair) = self.hashmap_iter.next() {
let (id, _) = pair;
if id % 2 == 0 {
return Some(pair);
}
}
None
}
}
impl<'a> State<'a> for TmpPartialState<'a> {
type It = StateIter<'a>;
fn objects(&self) -> Self::It {
StateIter {
hashmap_iter: self.full_state.objects(),
}
}
}
fn main() {
let full_state = FullState::new();
for (id, object) in full_state.objects() {
println!("{:?} -> {:?}", id, object);
}
println!("---");
let partial_state = TmpPartialState::new(&full_state);
for (id, object) in partial_state.objects() {
println!("{:?} -> {:?}", id, object);
}
}
(https://play.rust-lang.org/?gist=5b0140649e250e6daa6004e97272fa33)
Может я какое-то более простое решение упускаю из виду? Нет ни у кого идей?