Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/rust/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Rust 无法返回对局部变量的引用_Rust_Reference_Borrow Checker - Fatal编程技术网

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())
    }
}