【问题标题】:How to insert sized traits into a collection如何将大小特征插入到集合中
【发布时间】:2018-08-20 06:20:54
【问题描述】:

Playground

#[derive(Default)]
struct Bar;

#[derive(Default)]
struct Baz;

fn main() {
    let mut vec = Vec::<Box<dyn Default>>::new();
//                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `std::default::Default` cannot be made into an object
    vec.push(Box::new(Bar));
    vec.push(Box::new(Baz));
}

Default 是一个 sized Trait,表示你是 cannot convert it to a trait object

对于上面的示例,是否有解决方法,以便我可以将大小特征存储在 Vec(或任何其他集合)中?

【问题讨论】:

  • 我认为没有任何解决方法。拥有默认值向量有什么意义?它应该如何工作?
  • 你可以调用 trait 提供的方法(在本例中为 default),就像使用任何其他 trait 一样。
  • 你想做工厂吗?
  • @hellow 这是一个不需要self 的工厂函数。尝试使用一些已经存在的对象(例如 obj.default())来调用它是没有意义的。
  • @ozkriff 我已将这一点添加到我的答案中

标签: rust


【解决方案1】:

由于对象安全规则,您不能这样做。该规则说,方法返回具体类型本身的特征不能成为特征对象。原因是 trait 对象会知道具体类型。

此外,这个 trait 没有方法(一个接受 self 的函数),因此没有必要从中创建一个 trait 对象。

herethereblog article 中查看有关此规则的更多信息。

另见this question


这条规则非常直观:您希望您的代码做什么?

#[derive(Default)]
struct Bar;

#[derive(Default)]
struct Baz;

fn main() {
    let mut vec = Vec::<Box<dyn Default>>::new();
    vec.push(Box::new(Bar));
    vec.push(Box::new(Baz));

    vec.first().unwrap()::new();
    // Whatever the syntax should be, what do you expect this to return?
    // This type cannot be know at compile time.
}

【讨论】:

  • 我多久希望规则是相反的:即允许对此类特征进行装箱等...但只允许访问其接口的子集,该子集是对象安全的.
  • @MatthieuM。我认为这是可能的,并且可以追溯。让我们做一个 RFC ;)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-04-23
  • 1970-01-01
  • 2022-08-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-03-30
相关资源
最近更新 更多