“未实现大小"是什么意思?意思是? [英] What does "Sized is not implemented" mean?

查看:23
本文介绍了“未实现大小"是什么意思?意思是?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我写了以下代码:

use std::io::{IoResult, Writer};
use std::io::stdio;

fn main() {
    let h = |&: w: &mut Writer| -> IoResult<()> {
        writeln!(w, "foo")
    };
    let _ = h.handle(&mut stdio::stdout());
}

trait Handler<W> where W: Writer {
    fn handle(&self, &mut W) -> IoResult<()>;
}

impl<W, F> Handler<W> for F
where W: Writer, F: Fn(&mut W) -> IoResult<()> {
    fn handle(&self, w: &mut W) -> IoResult<()> { (*self)(w) }
}

然后 rustc 在我的终端中:

And then rustc in my terminal:

$ rustc writer_handler.rs
writer_handler.rs:8:15: 8:43 error: the trait `core::marker::Sized` is not implemented for the type `std::io::Writer`
writer_handler.rs:8     let _ = h.handle(&mut stdio::stdout());
                                  ^~~~~~~~~~~~~~~~~~~~~~~~~~~~
writer_handler.rs:8:15: 8:43 error: the trait `core::marker::Sized` is not implemented for the type `std::io::Writer`
writer_handler.rs:8     let _ = h.handle(&mut stdio::stdout());
                                  ^~~~~~~~~~~~~~~~~~~~~~~~~~~~

为什么需要这个 Writer 来实现 Sized?在我看来,不需要 Sized .在保持 trait Handler 有这个通用参数的同时我应该做什么?

Why is this Writer required to implement Sized? It appears to me that the Sized is not needed. What I should do while keeping trait Handler to have this generic argument?

在 Rust 1.0 中,这个类似的代码产生了同样的问题:

In Rust 1.0, this similar code produces the same problem:

use std::io::{self, Write};

fn main() {
    handle(&mut io::stdout());
}

fn handle(w: &mut Write) -> io::Result<()> {
    handler(w)
}

fn handler<W>(w: &mut W) -> io::Result<()>
where
    W: Write,
{
    writeln!(w, "foo")
}

出现错误:

error[E0277]: the trait bound `std::io::Write: std::marker::Sized` is not satisfied
 --> src/main.rs:8:5
  |
8 |     handler(w)
  |     ^^^^^^^ `std::io::Write` does not have a constant size known at compile-time
  |
  = help: the trait `std::marker::Sized` is not implemented for `std::io::Write`
  = note: required by `handler`

更高版本的 Rust 有错误

Later versions of Rust have the error

error[E0277]: the size for values of type `dyn std::io::Write` cannot be known at compilation time
  --> src/main.rs:8:13
   |
8  |     handler(w)
   |             ^ doesn't have a size known at compile-time
...
11 | fn handler<W>(w: &mut W) -> io::Result<()>
   |    ------- - required by this bound in `handler`
   |
   = help: the trait `std::marker::Sized` is not implemented for `dyn std::io::Write`
   = note: to learn more, visit <https://doc.rust-lang.org/book/ch19-04-advanced-types.html#dynamically-sized-types-and-the-sized-trait>

推荐答案

Sized trait 非常特殊,在大多数情况下它是类型参数的默认绑定.它表示在编译时具有固定大小的值,例如 u8(1 字节)或 &u32(具有 64 位指针的平台上的 8 字节)等. 这些值是灵活的:它们可以放在堆栈上并移到堆上,并且通常按值传递,因为编译器知道它需要多少空间 - 无论值在哪里.

The Sized trait is rather special, so special that it is a default bound on type parameters in most situations. It represents values that have a fixed size known at compile time, like u8 (1 byte) or &u32 (8 bytes on a platform with 64-bit pointers) etc. These values are flexible: they can be placed on the stack and moved onto the heap, and generally passed around by-value, as the compiler knows how much space it needs where-ever the value goes.

未确定大小的类型受到更多限制,并且 Writer 类型的值没有确定大小:它抽象地表示某些实现 Writer 的未指定类型,不知道实际类型是什么.由于不知道实际类型,因此无法知道大小:一些大类型是 Writer ,一些小类型是.Writer 是 trait 对象的一个​​例子,目前它只能出现在指针后面的已执行代码中.常见示例包括 &Writer&mut WriterBox.

Types that aren't sized are much more restricted, and a value of type Writer isn't sized: it represents, abstractly, some unspecified type that implements Writer, with no knowledge of what the actual type is. Since the actual type isn't known, the size can't be known: some large types are Writers, some small types are. Writer is one example of a trait object, which at the moment, can only appear in executed code behind a pointer. Common examples include &Writer, &mut Writer, or Box<Writer>.

这解释了为什么 Sized 是默认值:它通常是人们想要的.

This explains why Sized is the default: it is often what one wants.

无论如何,对于您的代码,这是因为您使用 handleh,这是一个 Fn(&mut Writer) ->IoResult<()>.如果我们将其与 F 匹配: Fn(&mut W) ->IoResult<()> 类型的Handle 是为我们发现W = Writer 实现的,也就是我们尝试使用handle 带有特征对象 &mut Writer,而不是某些具体类型 W&mut W.这是非法的,因为 trait 和 impl 中的 W 参数默认都有一个 Sized 绑定,如果我们手动用 ?Sized 覆盖它> 然后一切正常:

In any case, for your code, this is popping up because you're using handle with h, which is a Fn(&mut Writer) -> IoResult<()>. If we match this against the F: Fn(&mut W) -> IoResult<()> type that Handle is implemented for we find that W = Writer, that is, we're trying to use handle with the trait object &mut Writer, not a &mut W for some concrete type W. This is illegal because the W parameters in both the trait and the impl are defaulting to have a Sized bound, if we manually override it with ?Sized then everything works fine:

use std::io::{IoResult, Writer};
use std::io::stdio;

fn main() {
    let h = |&: w: &mut Writer| -> IoResult<()> {
        writeln!(w, "foo")
    };
    let _ = h.handle(&mut stdio::stdout());
}

trait Handler<W: ?Sized> where W: Writer {
    fn handle(&self, &mut W) -> IoResult<()>;
}

impl<W: ?Sized, F> Handler<W> for F
where W: Writer, F: Fn(&mut W) -> IoResult<()> {
    fn handle(&self, w: &mut W) -> IoResult<()> { (*self)(w) }
}

对于 Rust 1.0 代码:

And for the Rust 1.0 code:

use std::io::{self, Write};

fn main() {
    handle(&mut io::stdout());
}

fn handle(w: &mut Write) -> io::Result<()> {
    handler(w)
}

fn handler<W: ?Sized>(w: &mut W) -> io::Result<()>
where
    W: Write,
{
    writeln!(w, "foo")
}

我还写了一篇关于 Sized博客文章code> 和一般的 trait 对象,其中有更多细节.

I also wrote a blog post about Sized and trait objects in general which has a little more detail.

这篇关于“未实现大小"是什么意思?意思是?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆