gpt4 book ai didi

rust - 为什么生成器函数需要 sized trait 来生成 Rc

转载 作者:行者123 更新时间:2023-11-29 08:15:35 24 4
gpt4 key购买 nike

这段代码工作正常(playground):

use std::rc::Rc;

trait Foo {
fn foo(&self);
}

struct Bar<T> {
v: Rc<T>,
}

impl<T> Bar<T> where
T: Foo {
fn new(rhs: Rc<T>) -> Bar<T> {
Bar{v: rhs}
}
}

struct Zzz {
}

impl Zzz {
fn new() -> Zzz {
Zzz{}
}
}

impl Foo for Zzz {
fn foo(&self) {
println!("Zzz foo");
}
}

fn make_foo() -> Rc<Foo> {
Rc::new(Zzz{})
}

fn main() {
let a = Bar::new(Rc::new(Zzz::new()));
a.v.as_ref().foo()
}

但是如果我像下面那样制作一个包装器来生成 Rc,编译器会提示缺少大小特征(playground)

fn make_foo() -> Rc<dyn Foo> {
Rc::new(Zzz::new())
}

fn main() {
let a = Bar::new(make_foo());
a.v.as_ref().foo()
}

在这两种情况下,Bar::new 都接收到相同类型 Rc 的参数,为什么 Rust 编译器的 react 不同?

最佳答案

默认情况下,所有类型变量都假定为 Sized .例如,在 Bar 的定义中结构,有一个隐含的 Sized约束,像这样:

struct Bar<T: Sized> {
v: Rc<T>,
}

对象 dyn Foo 不能Sized因为 Foo 的每个可能实现可能有不同的尺寸,因此没有一种尺寸可供选择。但是您正在尝试实例化 Bar<dyn Foo> .

解决方法是选择退出 Sized T 的特征:

struct Bar<T: ?Sized> {
v: Rc<T>,
}

并且在实现的上下文中:

impl<T: ?Sized> Bar<T>
where
T: Foo

?Sized其实不是约束,而是放宽了已有的Sized约束,因此不需要。

选择退出 Sized 的后果是不是 Bar impl 中的方法 block 可以使用 T , 除了引用。

关于rust - 为什么生成器函数需要 sized trait 来生成 Rc<T>?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55061664/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com