ITADN

litemap: Consider returning concrete types on `LiteMap::{iter,iter_mut,keys,values}`

#8054Opennicopap 创建于 2026-06-09
good first issuehelp wantedC-zerovec
N
nicopapcommented
## What I wanted I needed to `.clone()` the return value of `LiteMap::iter` (which is much cheaper than cloning the whole map). ## What happened ```rust let my_map = LiteMap::new(); let my_iter = my_map.iter(); let iter_clone = my_iter.clone(); // ^^^ Compilation error! ``` ## Current workaround It's still possible to get an iterator that is clonable as follow: ```rust let my_map = LiteMap::new(); let my_iter = (&my_map).into_iter(); let iter_clone = my_iter.clone(); // ^_^ works fine! ``` ## Possible solution Instead of returning `impl DoubleEndedIterator<Item = _>`, methods like `LiteMap::iter` could return the same type as `<&'_ LiteMap as IntoIterator>::IntoIter` (that would be `<S as StoreIterable<'a, K, V>>::KeyValueIter`) ## More context I was using the `serde_iter` crate to serialize through a view type my base struct. But for it to work, I needed my iterator to be `Clone`. I expected the return type of `.iter()` to be `Clone`, since that's how the std lib works. I was specifically using `serde_iter` to avoid having to create a new owned struct and cloning all my values (the actual use-case `Bar` is much larger). The view pattern was as follow: <details> <summary>Code listing</summary> ```rust struct Bar { some: i32, field: i32 } struct Foo { bars: Vec<BarId> } struct Foos { name: String, foos: LiteMap<FooId, Foo>, bars: LiteMap<BarId, Bar>, } #[derive(Serialize)] struct ViewFoo<'a, I: IntoIterator<Item = (&'a BarId, &'a Bar)> + Clone> { #[serde(with = "serde_iter::map")] bars: I, } #[derive(Serialize)] struct ViewFoos<'a, V: Serialize, I: IntoIterator<Item = (&'a FooId, V)> + Clone> { name: &'a str #[serde(with = "serde_iter::map")] foos: I, } impl Serialize for Foos { // I want to serialize to: '{ "name": "the_name", foos: { // "foo1": { "bars": { // "bar1": { "some": 1, "field": 32 }, // "bar2": { "some": 2, "field": 42 } // }}, // "foo2": { "bars": { // "bar3": { "some": 3, "field": 52 }, // "bar4": { "some": 4, "field": 62 } // }} // }}' fn serialize<S: serde::Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> { let ser_foos = ViewFoos { name: &self.name, foos: self.foos.iter().map(|(id, foo)| { (id, ViewFoo { bars: foo.bars.iter().map(|id| (id, &self.bars[id])) }) }) }; ser_foos.serialize(serializer) } } ``` </details> Since the types get quite long (because we have those generic structs that themselves contain the iterator types, which may become quite long) the error message wasn't very helpful in pointing out from where the error came. (in this case, it is `self.foos.iter()` and `foo.bars.iter()`) and it took me a bit of time to find a fix.
1 条评论