当其中一个是本地引用时,如何为类型约束中的引用编写生命周期?
Posted
技术标签:
【中文标题】当其中一个是本地引用时,如何为类型约束中的引用编写生命周期?【英文标题】:How do I write the lifetimes for references in a type constraint when one of them is a local reference? 【发布时间】:2017-11-04 16:55:54 【问题描述】:我有一个 trait Matrix
和泛型函数 semi_def<T: Matrix>(x: &T)
,我想对这个 trait 进行操作。该函数需要在T
上实现运算符特征,例如Mul
。但是,如果其中一个引用是对局部变量的,我似乎无法让生命快乐。当其中一个只是本地临时引用时,如何为类型约束中的引用编写生命周期?
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()
这给出了这个错误:
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 | |
| |_^
【问题讨论】:
【参考方案1】:您需要更高级别的特征边界 (HRTB),即 are described in the advanced Rust book Rustonomicon 和 on Stack Overflow。它们允许类型约束说明 trait 不仅必须针对具有特定生命周期的引用实现,而且必须针对任何生命周期实现。他们使用where for<>
语法。下面是函数定义,表明对T
的任何两个引用都需要实现Mul
:
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
因为其中一个引用实际上具有生命周期'a
,而不是本地生命周期,所以可以用稍微宽松的约束来编写:
fn semi_def<'a, T: Matrix>(x: &'a T) -> T
where
for<'b> &'b T: Mul<&'a T, Output = T>,
&(*x).clone().transpose() * x
这个问答是基于a question我在 Rust 用户邮件中询问的,我将其清理并带到这里以供未来的 Rustaceans 使用。
【讨论】:
以上是关于当其中一个是本地引用时,如何为类型约束中的引用编写生命周期?的主要内容,如果未能解决你的问题,请参考以下文章
如何为本地引用的节点模块指定 node_modules 文件夹