Owned Chars
Chars
but keeping a strong reference (Rc
) to the string.
#![allow(unused)] fn main() { mod rcchars { pub struct RcChars { rc: std::rc::Rc<String>, index: usize } impl Iterator for RcChars { type Item = char; fn next(&mut self) -> Option<Self::Item> { let s = self.rc.get(self.index..)?; let c = s.chars().next()?; self.index += c.len_utf8(); Some(c) } } impl RcChars { pub fn from_rc(rc: std::rc::Rc<String>) -> Self { Self { rc, index: 0 } } } impl From<std::rc::Rc<String>> for RcChars { fn from(value: std::rc::Rc<String>) -> Self { Self::from_rc(value) } } } use {std::rc::Rc, rcchars::RcChars}; { let rc = Rc::new("abc".to_string()); let rcc = RcChars::from(rc.clone()); drop(rc); assert_eq!(rcc.collect::<Vec<_>>(), ['a', 'b', 'c']); } { let rc = Rc::new("abc".to_string()); let rcc = RcChars::from(rc); let rcc = Box::new(rcc); assert_eq!(rcc.collect::<Vec<_>>(), ['a', 'b', 'c']); } }
Solutions
- The one in hidden code (slightly compacted).
- Implementation used in rattlescript.
- Same solution but with some extra comments.
- Another solution. I prefer this one.
- There's an even simpler version that even an AI can generate (don't do that for
unsafe
code in production), but I dislike it for several reasons, even though it's mostly sound.