gpt4 book ai didi

rust - 特征实现大小

转载 作者:行者123 更新时间:2023-11-29 07:42:28 24 4
gpt4 key购买 nike

我知道 traits 和 slices 是没有大小的,即在编译时不可能知道它们的大小,例如任何类型都可以实现特征,但该类型可能无法确定大小。

然而,这个示例代码是否意味着每个实现特征 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),并可以从任何其他实现特定特征(我们将其命名为 Foo)。

我通过引用而不是值传递 Foo 解决了这个问题,但我不确定如果实现者需要 Sized 编译器为什么会提示。

最佳答案

为什么不起作用?

当您说每个 Foo 都是 Sized 时,您是在隐瞒真相。是的,每个 Foo 都是 Sized 但实际上每个类型在某个时候都有给定的大小。真正重要的信息是你没有说这个尺寸是多少。想象一下,如果 Bar(i64)Foo,但是 Baz(i8) 也是 Foo(它们是Sized,对吗?)你确定 Foo 的大小是多少?它是 8 字节还是 1 字节长?编译器在尝试为您的函数 from(foo: Foo) 生成代码时会询问此问题。通常,Sized 以“可能”的形式使用,语法为 ?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 ,但它与您的原始问题无关。)

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

关于rust - 特征实现大小,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31515921/

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