我的借款检查员喝醉了吗?
Is my borrow checker drunk?
reference must be valid for the block at 50:74...
...but borrowed value is only valid for the block at 50:74
对。那么问题是什么?
有问题的区块:
pub fn git_upload_pack(self: &mut GitConnect) -> Result<String, &str> {
let c = format!("git-upload-pack {}[=10=]host={}[=10=]", self.repo.path, self.repo.domain);
let mut out = String::new();
let data = try!(self.command(c.as_slice()));
for line in data.iter() {
out.push_str(from_utf8(line.as_slice()).unwrap());
}
Ok(out)
}
self.command
:
fn command(self: &mut GitConnect, command: &str) -> Result<Vec<Vec<u8>>, &str> {
完整错误:
src/protocol/git_connect.rs:54:38: 54:39 error: `c` does not live long enough
src/protocol/git_connect.rs:54 let data = try!(self.command(c.as_slice()));
^
<std macros>:1:1: 6:60 note: in expansion of try!
src/protocol/git_connect.rs:54:20: 54:53 note: expansion site
src/protocol/git_connect.rs:50:75: 61:6 note: reference must be valid for the anonymous lifetime #1 defined on the block at 50:74...
src/protocol/git_connect.rs:50 pub fn git_upload_pack(self: &mut GitConnect) -> Result<String, &str> {
src/protocol/git_connect.rs:51 let c = format!("git-upload-pack {}[=12=]host={}[=12=]", self.repo.path, self.repo.domain);
src/protocol/git_connect.rs:52
src/protocol/git_connect.rs:53 let mut out = String::new();
src/protocol/git_connect.rs:54 let data = try!(self.command(c.as_slice()));
src/protocol/git_connect.rs:55
...
src/protocol/git_connect.rs:50:75: 61:6 note: ...but borrowed value is only valid for the block at 50:74
src/protocol/git_connect.rs:50 pub fn git_upload_pack(self: &mut GitConnect) -> Result<String, &str> {
src/protocol/git_connect.rs:51 let c = format!("git-upload-pack {}[=12=]host={}[=12=]", self.repo.path, self.repo.domain);
src/protocol/git_connect.rs:52
src/protocol/git_connect.rs:53 let mut out = String::new();
src/protocol/git_connect.rs:54 let data = try!(self.command(c.as_slice()));
我觉得这像是一个错误。
这个签名:
fn command(self: &mut GitConnect, command: &str) -> Result<Vec<Vec<u8>>, &str>
根据lifetime elision rules,应该相当于这个:
fn command<'a, 'b>(self: &'a mut GitConnect, command: &'b str) -> Result<Vec<Vec<u8>>, &'a str>
事实上,如果您重写 command()
以使用此扩展变体,它应该可以编译。此外,如果您使用 shorthand self
参数定义:
fn command(&mut self, command: &str) -> Result<Vec<Vec<u8>>, &str>
然后它也编译。
目前看来
fn command(self: &mut GitConnect, command: &str) -> Result<Vec<Vec<u8>>, &str>
等同于
fn command<'a>(self: &'a mut GitConnect, command: &'a str) -> Result<Vec<Vec<u8>>, &'a str>
出于正确的原因给出了完全相同的错误,因为存在生命周期错误:command
参数的生命周期被断言为与 self
相同,因此它不适用于本地生命周期短于 self
.
之一的变量
reference must be valid for the block at 50:74... ...but borrowed value is only valid for the block at 50:74
对。那么问题是什么?
有问题的区块:
pub fn git_upload_pack(self: &mut GitConnect) -> Result<String, &str> {
let c = format!("git-upload-pack {}[=10=]host={}[=10=]", self.repo.path, self.repo.domain);
let mut out = String::new();
let data = try!(self.command(c.as_slice()));
for line in data.iter() {
out.push_str(from_utf8(line.as_slice()).unwrap());
}
Ok(out)
}
self.command
:
fn command(self: &mut GitConnect, command: &str) -> Result<Vec<Vec<u8>>, &str> {
完整错误:
src/protocol/git_connect.rs:54:38: 54:39 error: `c` does not live long enough
src/protocol/git_connect.rs:54 let data = try!(self.command(c.as_slice()));
^
<std macros>:1:1: 6:60 note: in expansion of try!
src/protocol/git_connect.rs:54:20: 54:53 note: expansion site
src/protocol/git_connect.rs:50:75: 61:6 note: reference must be valid for the anonymous lifetime #1 defined on the block at 50:74...
src/protocol/git_connect.rs:50 pub fn git_upload_pack(self: &mut GitConnect) -> Result<String, &str> {
src/protocol/git_connect.rs:51 let c = format!("git-upload-pack {}[=12=]host={}[=12=]", self.repo.path, self.repo.domain);
src/protocol/git_connect.rs:52
src/protocol/git_connect.rs:53 let mut out = String::new();
src/protocol/git_connect.rs:54 let data = try!(self.command(c.as_slice()));
src/protocol/git_connect.rs:55
...
src/protocol/git_connect.rs:50:75: 61:6 note: ...but borrowed value is only valid for the block at 50:74
src/protocol/git_connect.rs:50 pub fn git_upload_pack(self: &mut GitConnect) -> Result<String, &str> {
src/protocol/git_connect.rs:51 let c = format!("git-upload-pack {}[=12=]host={}[=12=]", self.repo.path, self.repo.domain);
src/protocol/git_connect.rs:52
src/protocol/git_connect.rs:53 let mut out = String::new();
src/protocol/git_connect.rs:54 let data = try!(self.command(c.as_slice()));
我觉得这像是一个错误。
这个签名:
fn command(self: &mut GitConnect, command: &str) -> Result<Vec<Vec<u8>>, &str>
根据lifetime elision rules,应该相当于这个:
fn command<'a, 'b>(self: &'a mut GitConnect, command: &'b str) -> Result<Vec<Vec<u8>>, &'a str>
事实上,如果您重写 command()
以使用此扩展变体,它应该可以编译。此外,如果您使用 shorthand self
参数定义:
fn command(&mut self, command: &str) -> Result<Vec<Vec<u8>>, &str>
然后它也编译。
目前看来
fn command(self: &mut GitConnect, command: &str) -> Result<Vec<Vec<u8>>, &str>
等同于
fn command<'a>(self: &'a mut GitConnect, command: &'a str) -> Result<Vec<Vec<u8>>, &'a str>
出于正确的原因给出了完全相同的错误,因为存在生命周期错误:command
参数的生命周期被断言为与 self
相同,因此它不适用于本地生命周期短于 self
.