Rust 无法返回对局部变量的引用
我有一个特点:Rust 无法返回对局部变量的引用,rust,reference,borrow-checker,Rust,Reference,Borrow Checker,我有一个特点: pub trait HasQuux { fn quux(&self) -> &Quux; } 大多数实现这一点的结构都有一个qux字段,可能是嵌套的,它们可以返回对该字段的引用。e、 g pub struct Foo { ... q: Quux, ... } impl HasQuux for Foo { fn quux(&self) -> &Quux { &self.q
pub trait HasQuux {
fn quux(&self) -> &Quux;
}
大多数实现这一点的结构都有一个qux
字段,可能是嵌套的,它们可以返回对该字段的引用。e、 g
pub struct Foo {
...
q: Quux,
...
}
impl HasQuux for Foo {
fn quux(&self) -> &Quux {
&self.q
}
}
如何为必须计算其Quux的结构实现HasQuux
这一实施:
impl HasQuux for Bar {
fn quux(&self) -> &Quux {
let q: Quux = self.calc_quux();
&q
}
}
原因:
error[E0515]: cannot return reference to local variable `q`
--> /home/fadedbee/test.rs:38:3
|
38 | &q
| ^^ returns a reference to data owned by the current function
我渴望qux()
返回一个引用,因为99%实现hasqux
的结构都有qux
字段
我明白为什么这是不可能的
我是否可以创建一个临时Quux
,其生存期与Bar
的生存期相匹配,并返回对它的引用
还是有更好的解决方案
我可以创建一个临时的Quux
,它的生存期与Bar的生存期匹配,并返回对它的引用吗
简单的回答是:你不能。您可以做的是让quox
返回一份(写入时复制,而不是复制):
上面的类型在其实现中使用了unsafe,但提供了一个完全安全的接口(据我所知,不安全代码永远无法100%确定)。安全注释中提到的另一个borrow_mut()
不能由外部代码执行,因为Lazy
的字段是私有的。尽管如此,如果Lazy
的定义修改不正确,编译器无法捕获错误,因为我们使用safe
来说服它我们知道我们在做什么
使用此帮助器类型,我们可以为Bar
提供简单而安全的hasqux
实现:
struct Bar {
cached_q: lazy::Lazy<Quux>,
}
impl Bar {
fn calc_quux(&self) -> Quux {
Quux
}
}
impl HasQuux for Bar {
fn quux(&self) -> &Quux {
self.cached_q.ensure(|| self.calc_quux())
}
}
结构栏{
缓存的_q:lazy::lazy,
}
注入棒{
fn计算(自我)->quux{
库克斯
}
}
酒吧的简易哈斯库克斯酒店{
fn quux(&self)->&quux{
self.cached_q.sure(| | self.calc_qux())
}
}
1. 或者只使用
once\u单元格中的类型,其方法与上面定义的Lazy::sure()
完全相同
我可以创建一个临时的Quux
,它的生存期与Bar的生存期匹配,并返回对它的引用吗
简单的回答是:你不能。您可以做的是让quox
返回一份(写入时复制,而不是复制):
上面的类型在其实现中使用了unsafe,但提供了一个完全安全的接口(据我所知,不安全代码永远无法100%确定)。安全注释中提到的另一个borrow_mut()
不能由外部代码执行,因为Lazy
的字段是私有的。尽管如此,如果Lazy
的定义修改不正确,编译器无法捕获错误,因为我们使用safe
来说服它我们知道我们在做什么
使用此帮助器类型,我们可以为Bar
提供简单而安全的hasqux
实现:
struct Bar {
cached_q: lazy::Lazy<Quux>,
}
impl Bar {
fn calc_quux(&self) -> Quux {
Quux
}
}
impl HasQuux for Bar {
fn quux(&self) -> &Quux {
self.cached_q.ensure(|| self.calc_quux())
}
}
结构栏{
缓存的_q:lazy::lazy,
}
注入棒{
fn计算(自我)->quux{
库克斯
}
}
酒吧的简易哈斯库克斯酒店{
fn quux(&self)->&quux{
self.cached_q.sure(| | self.calc_qux())
}
}
1.
或者只使用once\u cell
板条箱中的类型,其方法完全等同于上面定义的Lazy::sure()
。谢谢,这是一个非常全面的答案。我不得不重新考虑我的结构,因为使用Cow在源的其余部分产生了太多的噪音。谢谢,这是一个非常全面的答案。我不得不重新考虑我的结构,因为使用Cow在源的其余部分产生了太多的噪音。
struct Bar {
cached_q: lazy::Lazy<Quux>,
}
impl Bar {
fn calc_quux(&self) -> Quux {
Quux
}
}
impl HasQuux for Bar {
fn quux(&self) -> &Quux {
self.cached_q.ensure(|| self.calc_quux())
}
}