Reputation: 1702
pub struct Decoder<'a> {
reader: &'a mut io::Reader+'a,
}
impl<'a> Decoder<'a> {
pub fn from_reader(r: &'a mut io::Reader) -> Decoder<'a> {
Decoder {
reader: r,
}
}
}
// shortcut method to accept bytes to decode
pub fn decode<'a, T: Decodable<Decoder<'a>, IoError>>(data: Vec<u8>) -> DecodeResult<T> {
let mut r = MemReader::new(data);
let mut decoder = Decoder::from_reader(&mut r); // error: `r` does not live long enough
Decodable::decode(&mut decoder)
}
I have two question here.
reader: &'a mut io::Reader+'a
. Which I was referencing the code from the std json encoder.Vec<u8>
with MemReader, so that I can just interfacing io::Reader. But the compiler complains error:
rdoes not live long
. How to make it right.Update: I upload the code to github.
Upvotes: 0
Views: 107
Reputation: 65712
The first 'a
means that the Reader
object itself has lifetime 'a
. The second 'a
means that the Reader
object doesn't contain references that outlive 'a
. Since Reader
is a trait, it could be implemented by a struct that has lifetime parameters. This bound applies to those potential lifetime parameters.
The problem is with the bound on T
: Decodable<Decoder<'a>, IoError>
references the lifetime parameter 'a
. However, the Decoder
you're creating references a local variable, whereas 'a
refers to a lifetime that lives longer than the function call (because it's an input parameter specified implicitly at the call site).
I think there's no way to make this function compile successfully without unsafe code for the moment. In fact, Encoder::buffer_encode
seems to be having the same issue (#14302) and uses a similar workaround. transmute
allows us to coerce the local lifetime to 'a
.
pub fn decode<'a, T: Decodable<Decoder<'a>, IoError>>(data: Vec<u8>) -> DecodeResult<T> {
let mut r = MemReader::new(data);
let mut decoder = unsafe { mem::transmute(Decoder::from_reader(&mut r)) };
Decodable::decode(&mut decoder)
}
Upvotes: 1