我正在尝试实现以下功能,该功能需要3个可选输入并从rust-mpd板条箱中从mpd客户端获取搜索结果。
fn load(
&mut self,
track: &Option<String>,
artist: &Option<String>,
album: &Option<String>
) -> Result<(), &'static str>{
println!("mpd, load method is invoked with:");
let mut query = Query::new();
if let Some(s) = track {
println!(" track: {}", &s);
query.and(Term::Tag(Cow::Borrowed("track")), s);
}
if let Some(s) = artist {
println!(" artist: {}", &s);
query.and(Term::Tag(Cow::Borrowed("artist")), s);
}
if let Some(s) = album {
println!(" album: {}", &s);
query.and(Term::Tag(Cow::Borrowed("album")), s);
}
//let musics = self.client.search(&query, Window(None));
let musics = self.client.search(&query, (1,2));
println!("Search result: {:?}", musics);
Ok(())
}
但是,当我尝试编译时,它告诉我:
error[E0499]: cannot borrow `query` as mutable more than once at a time
--> src/player/mpd.rs:62:13
|
57 | query.and(Term::Tag(Cow::Borrowed("track")), s);
| ----- first mutable borrow occurs here
...
62 | query.and(Term::Tag(Cow::Borrowed("artist")), s);
| ^^^^^
| |
| second mutable borrow occurs here
| first borrow later used here
error[E0499]: cannot borrow `query` as mutable more than once at a time
--> src/player/mpd.rs:67:13
|
62 | query.and(Term::Tag(Cow::Borrowed("artist")), s);
| ----- first mutable borrow occurs here
...
67 | query.and(Term::Tag(Cow::Borrowed("album")), s);
| ^^^^^
| |
| second mutable borrow occurs here
| first borrow later used here
error[E0502]: cannot borrow `query` as immutable because it is also borrowed as mutable
--> src/player/mpd.rs:71:41
|
67 | query.and(Term::Tag(Cow::Borrowed("album")), s);
| ----- mutable borrow occurs here
...
71 | let musics = self.client.search(&query, (1,2));
| ^^^^^^
| |
| immutable borrow occurs here
| mutable borrow later used here
如果我的方法有误,应该如何实现相同的功能?
答案 0 :(得分:3)
乍一看,可变借用应该以{{1}}块结尾,这将允许后续借用。但是,if let
中存在一个错误,该错误会导致借用延长到rust-mpd
的整个生命周期:Query::and
方法声明为:
query
对查询和的嵌入生存期都使用相同的生存期fn and<'b: 'a, V: 'b + Into<Cow<'b, str>>>(
&'a mut self, // <- Note the 'a lifetime here
term: Term<'b>,
value: V)
-> &'a mut Query<'a> // <- Note the **two** 'a lifetimes here
。该方法应这样声明:
'a
您应该向fn and<'b: 'a, V: 'b + Into<Cow<'b, str>>>(
&mut self,
term: Term<'b>,
value: V)
-> &mut Query<'a>
报告一个错误。
答案 1 :(得分:1)
如果您只想在非理想状态下使用库,则可以迭代地更新对Query
的可变引用,而不是直接使用它:
use mpd::{Query, Term}; // 0.0.12
use std::borrow::Cow;
fn load(
track: &Option<String>,
artist: &Option<String>,
album: &Option<String>,
) -> Result<(), &'static str> {
let mut query = Query::new();
let mut query = &mut query;
if let Some(s) = track {
query = query.and(Term::Tag(Cow::Borrowed("track")), s);
}
if let Some(s) = artist {
query = query.and(Term::Tag(Cow::Borrowed("artist")), s);
}
if let Some(s) = album {
query = query.and(Term::Tag(Cow::Borrowed("album")), s);
}
let mut client = mpd::Client::new(std::fs::File::open("/tmp/junk").unwrap()).unwrap();
let _musics = client.search(&query, (1, 2));
Ok(())
}