generics - ¿Cómo escribo las vidas para referencias en una restricción de tipo cuando una de ellas es una referencia local?
rust lifetime (1)
Necesita límites de rasgos de mayor rango (HRTB), que
se describen en el libro avanzado Rust Rustonomicon
y
en Stack Overflow
.
Permiten una restricción de tipo para decir que el rasgo debe implementarse no solo para referencias con una vida útil particular sino para cualquier vida útil.
Usan la sintaxis
where for<>
.
Aquí está la definición de la función que dice que se necesita una implementación de
Mul
para dos referencias a
T
:
fn semi_def<''a, T: Matrix>(x: &''a T) -> T
where
for<''b, ''c> &''b T: Mul<&''c T, Output = T>,
{
&(*x).clone().transpose() * x
}
Debido a que una de las referencias en realidad tiene la duración
''a
, no una duración local, esto podría escribirse con una restricción un poco más flexible:
fn semi_def<''a, T: Matrix>(x: &''a T) -> T
where
for<''b> &''b T: Mul<&''a T, Output = T>,
{
&(*x).clone().transpose() * x
}
Estas preguntas y respuestas se basan en una pregunta que hice sobre el envío de usuarios de Rust, que limpié y traje aquí para futuros Rustaceanos.
Tengo una
Matrix
rasgos y una función genérica
semi_def<T: Matrix>(x: &T)
que me gustaría operar en ese rasgo.
La función requiere un rasgo de operador, digamos
Mul
, implementado en
T
Sin embargo, parece que no puedo hacer felices las vidas si una de las referencias es a una variable local.
¿Cómo escribo los tiempos de vida de las referencias en la restricción de tipo cuando uno de ellos es solo una referencia temporal local?
use std::ops::Mul;
trait Matrix: Clone {
fn transpose(self) -> Self;
}
#[derive(Clone)]
struct DenseMatrix {
n_rows: usize,
n_columns: usize,
elements: Vec<f64>,
}
impl Matrix for DenseMatrix {
fn transpose(self) -> Self {
unimplemented!()
}
}
impl<''a, ''b> Mul<&''b DenseMatrix> for &''a DenseMatrix {
type Output = DenseMatrix;
fn mul(self, _rhs: &''b DenseMatrix) -> Self::Output {
unimplemented!()
}
}
fn semi_def<''a, T: Matrix>(x: &''a T) -> T
where
&''a T: Mul<&''a T, Output = T>,
{
&(*x).clone().transpose() * x
}
fn main() {}
lo que da este error:
error[E0597]: borrowed value does not live long enough
--> src/main.rs:31:6
|
31 | &(*x).clone().transpose() * x
| ^^^^^^^^^^^^^^^^^^^^^^^^ temporary value does not live long enough
32 | }
| - temporary value only lives until here
|
note: borrowed value must be valid for the lifetime ''a as defined on the function body at 27:1...
--> src/main.rs:27:1
|
27 | / fn semi_def<''a, T: Matrix>(x: &''a T) -> T
28 | | where
29 | | &''a T: Mul<&''a T, Output = T>,
30 | | {
31 | | &(*x).clone().transpose() * x
32 | | }
| |_^