I want to use a read
function like this:
let data = "text";
let res = read(data, |d| Result { text: d });
assert_eq!(res, Result { text: "text" });
The signature is
fn read<'a, R: ReadData<'a>>(data: &'a str, read_data: R) -> R::Result
Input and output data have a common lifetime.
This works until I explicitly write the type of the closure:
let data = "text";
let res = read(data, |d: &str| Result { text: d });
assert_eq!(res, Result { text: "text" });
This produces a compilation error:
error[E0495]: cannot infer an appropriate lifetime for lifetime parameter `'a` due to conflicting requirements
--> src\lib.rs:47:40
|
47 | let res = read(data, |d: &str| Result { text: d });
| ^^^^^^
|
note: first, the lifetime cannot outlive the anonymous lifetime #1 defined on the body at 47:30...
--> src\lib.rs:47:30
|
47 | let res = read(data, |d: &str| Result { text: d });
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
note: ...so that reference does not outlive borrowed content
--> src\lib.rs:47:55
|
47 | let res = read(data, |d: &str| Result { text: d });
| ^
note: but, the lifetime must be valid for the call at 47:19...
--> src\lib.rs:47:19
|
47 | let res = read(data, |d: &str| Result { text: d });
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
note: ...so type `Result<'_>` of expression is valid during the expression
--> src\lib.rs:47:19
|
47 | let res = read(data, |d: &str| Result { text: d });
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: aborting due to previous error
It may be necessary for me to explicitly specify the type when I change the input parameter &str
to another struct. In this case there is the same error. But this is fixed by deconstructing the object.
How do I specify a type in a closure?
I don't know, maybe my mistake elsewhere. So I give trait code and the impl of function:
pub trait ReadData<'a> {
type Result;
fn read_data(&self, data: &'a str) -> Self::Result;
}
impl<'a, F, R> ReadData<'a> for F where
F: Fn(&'a str) -> R,
R: ReadData<'a> {
type Result = R;
fn read_data(&self, data: &'a str) -> Self::Result {
self(data)
}
}