为什么 Weak::new() 不起作用,而 Rc::downgrade() 起作用?

eik*_*iko 2 rust

我正在创建一个返回Weak对特征对象的引用的函数。在找不到对象的情况下(它是一个查找函数),我想Weak使用以下方法返回一个空引用Weak::new()

use std::rc::{self, Rc, Weak};
use std::cell::RefCell;

pub trait Part {}

pub struct Blah {}

impl Part for Blah {}

fn main() {
    let blah = Blah {};
    lookup(Rc::new(RefCell::new(blah)));
}

fn lookup(part: Rc<RefCell<Part>>) -> Weak<RefCell<Part>> {
    if true {
        Rc::downgrade(&part)
    } else {
        Weak::new()
    }
}
Run Code Online (Sandbox Code Playgroud)

这样在编译的时候会出现如下错误:

use std::rc::{self, Rc, Weak};
use std::cell::RefCell;

pub trait Part {}

pub struct Blah {}

impl Part for Blah {}

fn main() {
    let blah = Blah {};
    lookup(Rc::new(RefCell::new(blah)));
}

fn lookup(part: Rc<RefCell<Part>>) -> Weak<RefCell<Part>> {
    if true {
        Rc::downgrade(&part)
    } else {
        Weak::new()
    }
}
Run Code Online (Sandbox Code Playgroud)

为什么我可以成功创建Weak<RefCell<Part>>fromRc::downgrade()但无法使用相同的类型创建新的弱引用 with Weak::new()

有没有办法让我注释Weak::new()来帮助编译器,或者我必须将其包装在 an 中Option以让用户知道未找到该部分?

工作最小示例

Art*_*mGr 5

推断的类型Weak::new()Weak<RefCell<Part>>,并且Part无法创建该部分,因为它是一个特征!

这就是Sized错误的全部内容。该特征不是一个具体的结构,它在编译时没有已知的大小,因此编译器不知道要分配多少空间。

为什么我可以成功创建Weak<RefCell<Part>>fromRc::downgrade()

这是因为Rc<RefCell<Part>>指向一个已经分配的结构。编译器可以使用特征指针引用它,即使它不知道它是特征Blah的实现还是其他实现Part

有没有办法让我注释Weak::new()来帮助编译器

您确实可以注释Weak::new(),将编译器指向Part您想要实例化的实现,如下所示:

use std::rc::{Rc, Weak};
use std::cell::RefCell;

pub trait Part {}

pub struct Blah {}

impl Part for Blah {}

fn main() {
    let blah = Blah {};
    lookup(Rc::new(RefCell::new(blah)));
}

fn lookup(part: Rc<RefCell<Part>>) -> Weak<RefCell<Part>> {
    if true {
        Rc::downgrade(&part)
    } else {
        Weak::<RefCell<Blah>>::new()
    }
}
Run Code Online (Sandbox Code Playgroud)

  • @eiko是的,[Weak::new](https://doc.rust-lang.org/nightly/std/rc/struct.Weak.html#method.new)保留内存,大概是为了避免额外的分支和内存需要将值设置为“Option”-al。但它留下的值未初始化。您不应该使用或初始化它。`Weak::upgrade` 将始终返回 `None`,因为引用计数器被初始化为零。 (2认同)