【问题标题】:Trait implementing Sized实现大小的特征
【发布时间】:2015-07-20 11:58:07
【问题描述】:

我知道特征和切片没有大小,即在编译时不可能知道它们的大小,例如任何类型都可以实现特征,但该类型可能没有大小。

但是,这个示例代码不是意味着每个实现了 trait Foo 的类型也需要实现 Sized 吗?

trait Foo: Sized {}

struct Bar(i64);

impl Foo for Bar {}

如果是这样,为什么这不起作用?

impl From<Foo> for Bar {
    fn from(foo: Foo) -> Bar {
        Bar(64)
    }
}
error[E0277]: the trait bound `Foo + 'static: std::marker::Sized` is not satisfied
 --> src/main.rs:7:6
  |
7 | impl From<Foo> for Bar {
  |      ^^^^^^^^^ `Foo + 'static` does not have a constant size known at compile-time
  |
  = help: the trait `std::marker::Sized` is not implemented for `Foo + 'static`

我想为库的使用者提供一个类型(我们将其命名为 Bar)并使其能够从任何其他实现特定特征的类型转换为 Bar(我们将其命名为 Foo) .

我通过通过引用而不是值传递 Foo 来解决它,但我不确定如果实现者需要 Sized,编译器为什么会抱怨。

【问题讨论】:

    标签: rust


    【解决方案1】:

    为什么它不起作用?

    当你说每个Foo 都是Sized 时,你有点对自己隐瞒真相。是的,每个Foo 都是Sized,但实际上每种类型在某个时候都有给定的大小。真正重要的信息是,您并没有说这个尺寸是多少。想象一下,如果Bar(i64)Foo,但Baz(i8) 也是Foo(它们都是Sized,对吧?)你确定Foo 的大小是多少?它是 8 字节还是 1 字节长?编译器在尝试为您的函数from(foo: Foo) 生成代码时会询问此问题。通常,Sized 宁可用于“maybe”样式,语法为?Sized,表示在编译时类型大小可能是未知的。

    如何解决?

    通常你会放弃: Sized 部分,并使用以下语法,这实际上是一种 C++ 模板;当给定具有给定大小的具体类型时,它为编译器提供了编写实际代码的草图。

    trait Foo {}
    
    struct Bar(i64);
    
    impl Foo for Bar {}
    
    impl<F: Foo> From<F> for Bar {
        fn from(foo: F) -> Bar {
            Bar(64)
        }
    }
    

    (这将 still error 基于 the fact that you cannot reimplement From because of the std crate,但与您的原始问题无关。)

    您还可以在函数的参数中使用引用特征对象&amp;Foo 语法。这会将您的调用从静态调度转换为动态调度 (read more here),但您不能在此处执行此操作,因为签名是由 trait 强加的。

    【讨论】:

      【解决方案2】:

      Foo 特征要求实现者为Sized。这并不意味着Foo 本身会有大小。您误解了第二个代码示例的语法,因此我不确定您实际上要做什么。你在找这个吗?

      impl From<i64> for Bar {
          fn from(val: i64) -> Bar {
              Bar(val)
          }
      }
      

      或者您想要一种从任何有符号整数构造Bar 的方法吗?

      我们在这里有一个XY problem

      【讨论】:

        猜你喜欢
        • 2019-12-08
        • 2021-11-14
        • 1970-01-01
        • 1970-01-01
        • 2022-08-03
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-07-19
        相关资源
        最近更新 更多