我想使用Peekable
作为新的cautious_take_while
操作的基础,该操作类似于IteratorExt
的take_while
,但不消耗第一个失败的项。(还有一个附带的问题,即这是否是一个好主意,是否有更好的方法在Rust中实现这个目标--我很乐意得到这方面的提示,但主要是想弄清楚我的代码在哪里出错)。
我尝试启用的API基本上是:
let mut chars = "abcdefg.".chars().peekable();
let abc : String = chars.by_ref().cautious_take_while(|&x| x != 'd');
let defg : String = chars.by_ref().cautious_take_while(|&x| x != '.');
// yielding (abc = "abc", defg = "defg")
我尝试过creating a MCVE here,但得到的结果是:
:10:5:10:19错误:无法移出借用的内容:10 chars.by_ref().谨慎_take_while(|x(& X)|x!=“.”);
就我所知,我在函数签名方面遵循了与Rust自己的TakeWhile
相同的模式,但是我在借位检查器中看到了不同的行为。有人能指出我做错了什么吗?
2条答案
按热度按时间b1uwtaje1#
by_ref()
的有趣之处在于它返回一个对自身的可变引用:因为
Iterator
特性是为指向Iterator* 类型的 * 可变指针实现的。标准的
take_while
函数可以正常工作,因为它使用了特征Iterator
,该特征会自动解析为&mut Peekable<T>
。但是你的代码不起作用,因为
Peekable
是一个结构体,而不是一个特征,所以你的CautiousTakeWhileable
必须指定类型,你试图获得它的所有权,但是你不能,因为你有一个可变指针。解决方案,请不要使用
Peekable<T>
,而要使用&mut Peekable<T>
。您还需要指定生存期:这个解决方案的一个奇怪的副作用是,现在不需要
by_ref
,因为cautious_take_while()
接受一个可变引用,所以它不会窃取所有权。take_while()
需要by_ref()
调用,因为它可以接受Peekable<T>
或&mut Peekable<T>
,它默认为第一个。通过by_ref()
调用,它将解析为第二个。现在我终于理解了它,我认为改变
struct CautiousTakeWhile
的定义,将peekable位包含到结构体本身中,这可能是个好主意。困难在于,如果我是对的,必须手动指定生存期。类似于:剩下的就比较简单了。
5sxhfpxr2#
这是一个棘手的问题!我将从代码的核心开始,然后尝试解释它(如果我理解的话...)。这也是一个丑陋的,不加糖的版本,因为我想减少附带的复杂性。
实际上,Rodrigo seems to have a good explanation,所以我会遵从这个,除非你想让我解释一些具体的东西。