反转str.split的结果

时间:2015-04-27 16:39:26

标签: string rust string-parsing

加入https://doc.rust-lang.org/std/str/struct.Split.html对字符串rev的结果有一个split方法

我收到以下错误

error: the trait `core::str::pattern::DoubleEndedSearcher<'_>` is not
implemented for the type `core::str::pattern::StrSearcher<'_, '_>` [E0277]
for part in "1:30".split(":").rev() {

我使用的代码

let mut length = 0;
let mut mult = 1;
for part in "1:30".split(":").rev() {
   length += mult * part.parse::<i32>().unwrap();
   mult *= 60;
}

3 个答案:

答案 0 :(得分:5)

问题是,rev()仅在Split迭代器上定义,只有它实现DoubleEndedIterator,但Split仅在DoubleEndedIterator实现DoubleEndedSearcher时才实现impl<'a, P> DoubleEndedIterator for Split<'a, P> where P: Pattern<'a>, P::Searcher: DoubleEndedSearcher<'a> 你分裂的模式满足DoubleEndedSearcher

&str

here您可以找到实际实现rev()的类型。显然,其中没有一种类型与split(":")模式相对应,因此当您在字符串上拆分时,您无法使用split(':')

在您的特定情况下,我猜,将DoubleEndedSearcher更改为Date() - 1(即在字符而不是字符串上拆分)就足够了,因为字符模式搜索器 实现{ {1}}。

Rust的这些特性(条件特征实现和特定于方法的特征边界)允许编写真正富有表现力的代码,但它们有时难以阅读。

答案 1 :(得分:5)

其他答案都是正确的,但我想指出rsplit。这可能更明显,更高效。

那么,为什么你不能使用rev?作为其他答案状态,它没有为StrSearcher实现。但为什么没有实现?来自DoubleEndedIterator文档:

  

Searcher和ReverseSearcher的impl需要遵循以下条件:

     
      
  • next()的所有结果需要以相反的顺序与next_back()的结果相同。
  •   
  • next()和next_back()需要表现为一系列值的两端,即他们不能相互走过&#34;。
  •   

使用字符串反转迭代器的问题是:

"baaab".split("aa") // -> ["b", "aa", "ab"];

但是,如果你从字符串的末尾开始,你会得到类似的东西:

"baaab".split("aa").rev() // -> ["b", "aa", "ba"]

这显然不是以不同顺序排列的同一组项目!

简单地说,你无法反转在字符串上拆分的迭代器,因为没有高效方式知道下一个结果是什么时候。您必须将整个字符串拆分为一个集合,然后反转该集合!

这就是rsplit存在的原因 - 它意味着从字符串的末尾开始并以有效的方式向左分割。

答案 2 :(得分:2)

TLDR StrSearcher(搜索字符串模式的类型)不会实现DoubleEndedSearcher,因此split迭代器没有实现DoubleEndedIterator,因此,您无法在其上调用rev

如果您查看rev页面上的文档,您会看到where Self: DoubleEndedIterator。这意味着rev定义为,当且仅当实现Iterator特征的类型时(Split具有DoubleEndedIterator特征的实现。

如果你向下看,你会看到:

impl<'a, P> DoubleEndedIterator for Split<'a, P>
where P: Pattern<'a>, P::Searcher: DoubleEndedSearcher<'a>

因此,DoubleEndedIterator 实施了Split当且仅当满足这两个条件时:P必须是Pattern且它定义的Searcher类型必须实现DoubleEndedSearcher

现在,您使用字符串文字作为模式,因此如果您查看documentation for the str type,则会看到:

impl<'a, 'b> Pattern<'a> for &'b str

其中,关联的Searcher类型定义为:

type Searcher = StrSearcher<'a, 'b>

几乎就在那里!点击documentation for StrSearcher和...

的链接

......没有DoubleEndedSearcher的实施。因此,所需的边界,并且rev无法在Split迭代器上使用。