为何未调用next(),Rust代码中t却指向字符D?
为什么这段Rust代码中变量
t指向字符'D'? 先看完整代码:
fn main() { let s = String::from("ADOBECODEBANC"); let mut iter = s.chars().peekable(); let it1 = *iter.by_ref().peekable().peek().unwrap(); println!("{}",it1); let t = *iter.peek().unwrap(); println!("{}",t); }
核心原因是临时创建的Peekable迭代器调用peek()时,会触发原迭代器的next()调用,导致原迭代器的位置前进,具体拆解如下:
初始状态:
iter是基于字符串"ADOBECODEBANC"的Chars迭代器包装的Peekable,此时底层迭代器指向第一个字符'A',且iter自身没有缓存任何元素。执行
iter.by_ref().peekable().peek():iter.by_ref()获取iter的可变引用,不会转移所有权;- 基于这个可变引用创建一个新的临时
Peekable迭代器; - 对这个临时
Peekable调用peek():由于它自身没有缓存元素,会调用底层迭代器(也就是&mut iter)的next()方法来获取元素; - 原
iter的next()方法会从底层Chars迭代器读取第一个字符'A'并返回,同时原iter的底层Chars迭代器位置前进到下一个字符'D'; - 临时
Peekable将'A'缓存起来,peek()返回这个值,所以it1是'A'。
临时
Peekable迭代器被销毁:它不会将缓存的'A'放回原iter的迭代器中,原iter的底层位置已经停留在'D'。执行
iter.peek():原iter自身的Peekable发现没有缓存元素,就从底层Chars迭代器读取当前指向的'D'并缓存,所以t的值是'D'。
内容的提问来源于stack exchange,提问作者Shivam Varshney
相关产品推荐
相关产品推荐

