2016-12-19 119 views
2

我试图在Rust中使用Snowball stemmer箱子来干掉一个单词向量。它应该是简单的,但借检查一直拒绝我的代码:两个可变借款发生在同一行?

// Read user input 
let input = stdin(); 
let mut stemmer = Stemmer::new("english").unwrap(); 
for line in input.lock().lines() { 
    let line = line.unwrap(); 
    let mut query: Vec<_> = line.split_whitespace().collect(); 
    for t in &mut query { 
     *t = stemmer.stem_str(t); 
    } 
    // … 
} 

借入检查说我有stemmer上线*t = stemmer.stem_str(t); 2条可变借入并拒绝我的代码。 (80行是for line in input.lock().lines()末块。)

57 18 error E0499 cannot borrow `stemmer` as mutable more than once at a time (first mutable borrow occurs here) (rust-cargo) 
57 18 error E0499 cannot borrow `stemmer` as mutable more than once at a time (second mutable borrow occurs here) (rust-cargo) 
80 5 info  E0499 first borrow ends here (rust-cargo) 

如果我直接调用stem()方法,我得到一个String,但我不能只叫as_str(),并期望获得的&str分配回*t,因为借款检查员抱怨“借来的价值不够长”。

57 18 error   borrowed value does not live long enough (temporary value created here) (rust-cargo) 
57 18 info   consider using a `let` binding to increase its lifetime (rust-cargo) 
57 42 info   temporary value only lives until here (rust-cargo) 
80 5 info   temporary value needs to live until here (rust-cargo) 

我不确定这是否与该库的实现细节有关,但我真的觉得在这里停滞不前。我从来没有想过要扼杀一批投入品会如此困难。

+2

'or_exit()'似乎不是一个宏,因为你在评论上面说的,因为'! '丢失(错字?)。另外:你可以添加完整的编译器错误? :) –

+0

@LukasKalbertodt这是在代码库中定义的东西,而不是标准库。我应该在这里简单地改变代码示例到'unwrap()'。我现在包含完整的错误。 –

回答

4

documentation of stem_str

它返回的STR参考仅仅是只要你不叫干或再次stem_str有效;因此,如果你在范围内有这样的参考,Rust的借阅者不会让其中一个人发挥作用。

大概,这是因为stemmer实现实际上有一些内部缓冲区,因为它被阻止存储这个词。

这就是为什么你不能在调用字符串的同时调用stem_str两次;这样做会使无效第一个字符串

我不能就这么叫as_str(),并期望获得的&str分配回*t

编译器是绝对正确一次。您正试图创建一个值,参考它,存储该参考,然后删除该值!这是一个内存漏洞,你不能这样做。

相反,收集String个向量:

for line in input.lock().lines() { 
    let line = line.unwrap(); 
    let mut query: Vec<_> = line.split_whitespace() 
     .map(|t| stemmer.stem(t)) 
     .collect(); 
} 

我会强烈建议阅读The Rust Programming Language和理解引用是如何工作的,他们阻止什么。在和之前,在之前做这个进入任何复杂的所有权。这些章节明确:

+0

我读过这本书,但显然这些概念还需要一些时间来消化。使用你的方法,我可以得到一个'String'矢量,但是有一些函数需要'Vec <&str>'。有没有一种方便的方法可以将'Vec ''转换成'Vec <&str>',或者避免编写需要'Vec <&str>'的函数并将其输入类型更改为'Vec '? –

+0

@JIXiang我也建议在SO上搜索以下问题:[将Vec 转换为Vec <&str>](http://stackoverflow.com/q/33216514/155423)。如果有用,您可以更改函数类型以接受'&str'或'String'。 – Shepmaster

+0

对。我先Google搜索了一下,但我似乎写了“Vector”而不是“Vec”,并且没有遇到Google的相关结果。感谢您指出这个问题。 –

相关问题