亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

什么“大小沒有實現”是什么意思?

什么“大小沒有實現”是什么意思?

慕少森 2019-08-13 17:09:26
什么“大小沒有實現”是什么意思?我寫了以下代碼: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 Fwhere W: Writer, F: Fn(&mut W) -> IoResult<()> {    fn handle(&self, w: &mut W) -> IoResult<()> { (*self)(w) }}然后rustc在我的終端:$ rustc writer_handler.rswriter_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這種通用論證的同時我應該做些什么?在Rust 1.0中,這個類似的代碼會產生同樣的問題: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`
查看完整描述

2 回答

?
烙印99

TA貢獻1829條經驗 獲得超13個贊

Sized特點是比較特殊的,如此特別,在大多數情況下,勢必對類型參數的默認值。它表示在編譯時已知固定大小的值,如u8(1個字節)或&u32(64位指針平臺上的8個字節)等。這些值很靈活:它們可以放在堆棧上并移到堆上并且通常按值傳遞,因為編譯器知道它需要多少空間。

未調整大小的類型受到更多限制,并且類型的值Writer未調整大?。核橄蟮乇硎緦崿F的某些未指定類型,Writer而不知道實際類型是什么。由于實際類型未知,因此無法知道大?。耗承┐笮褪?code>Writers,有些是小型。Writer是特征對象的一個示例,此時,它只能出現在指針后面的已執行代碼中。常見的例子包括&Writer&mut WriterBox<Writer>。

這解釋了為什么Sized是默認值:它通常是人們想要的。

在任何情況下,對于你的代碼,這是因為你正在使用handle而出現h,這是一個Fn(&mut Writer) -> IoResult<()>。如果我們將這與我們發現的F: Fn(&mut W) -> IoResult<()>類型相匹配,那就是我們嘗試使用trait對象,而不是某種具體類型。這是非法的,因為trait和impl中的參數都默認為有一個綁定,如果我們手動覆蓋它然后一切正常:HandleW = Writerhandle&mut Writer&mut WWWSized?Sized

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代碼:

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和特征對象的博客文章,其中有一些細節。


查看完整回答
反對 回復 2019-08-13
?
慕工程0101907

TA貢獻1887條經驗 獲得超5個贊

首先,請注意這h是一種實現的類型Fn(&mut Writer) -> IoResult<()>

h.handle正被召喚; 這個要看的話,在Handler這里實施WWriter-注意的是仔細:W  Writer,一個無膠式。該&mut stdio::stdout()因此將被強制轉換為&mut Writer特征的對象。這在理論上非常好,但是當被帶回實施時就會倒塌。當涉及到約束時,默認情況下它們是大小的,因此它會抱怨,Writer您嘗試分配的值W不是大小。

這里有兩個主要解決方案:

  1. 切換到使用具體的編寫器類型,h以便您處理大小的類型:

    use std::io::{IoResult, Writer, stdio, LineBufferedWriter};use std::io::stdio::StdWriter;fn main() {
        let h = |&: w: &mut LineBufferedWriter<StdWriter>| -> 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) }}
  2. 允許W成為未定義的類型。這是可以接受的,因為您只能通過引用使用它&mut W。如果您希望將其用作裸型,例如W按價值計算的方法,則不會這樣做。

    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) }}

我會建議支持一個unsized,W即使你沒有在這種情況下使用它 - 沒有理由它需要大小。


查看完整回答
反對 回復 2019-08-13
  • 2 回答
  • 0 關注
  • 517 瀏覽

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號