2 回答

TA貢獻(xiàn)1829條經(jīng)驗(yàn) 獲得超13個(gè)贊
的Sized
特點(diǎn)是比較特殊的,如此特別,在大多數(shù)情況下,勢(shì)必對(duì)類型參數(shù)的默認(rèn)值。它表示在編譯時(shí)已知固定大小的值,如u8
(1個(gè)字節(jié))或&u32
(64位指針平臺(tái)上的8個(gè)字節(jié))等。這些值很靈活:它們可以放在堆棧上并移到堆上并且通常按值傳遞,因?yàn)榫幾g器知道它需要多少空間。
未調(diào)整大小的類型受到更多限制,并且類型的值Writer
未調(diào)整大?。核橄蟮乇硎緦?shí)現(xiàn)的某些未指定類型,Writer
而不知道實(shí)際類型是什么。由于實(shí)際類型未知,因此無法知道大小:某些大型是Writer
s,有些是小型。Writer
是特征對(duì)象的一個(gè)示例,此時(shí),它只能出現(xiàn)在指針后面的已執(zhí)行代碼中。常見的例子包括&Writer
,&mut Writer
或Box<Writer>
。
這解釋了為什么Sized
是默認(rèn)值:它通常是人們想要的。
在任何情況下,對(duì)于你的代碼,這是因?yàn)槟阏谑褂?code>handle而出現(xiàn)h
,這是一個(gè)Fn(&mut Writer) -> IoResult<()>
。如果我們將這與我們發(fā)現(xiàn)的F: Fn(&mut W) -> IoResult<()>
類型相匹配,那就是我們嘗試使用trait對(duì)象,而不是某種具體類型。這是非法的,因?yàn)閠rait和impl中的參數(shù)都默認(rèn)為有一個(gè)綁定,如果我們手動(dòng)覆蓋它然后一切正常:Handle
W = Writer
handle
&mut Writer
&mut W
W
W
Sized
?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) }}
而對(duì)于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")}
我還寫了一篇關(guān)于Sized
和特征對(duì)象的博客文章,其中有一些細(xì)節(jié)。

TA貢獻(xiàn)1887條經(jīng)驗(yàn) 獲得超5個(gè)贊
首先,請(qǐng)注意這h
是一種實(shí)現(xiàn)的類型Fn(&mut Writer) -> IoResult<()>
。
h.handle
正被召喚; 這個(gè)要看的話,在Handler
這里實(shí)施W
是Writer
-注意的是仔細(xì):W 是 Writer
,一個(gè)無膠式。該&mut stdio::stdout()
因此將被強(qiáng)制轉(zhuǎn)換為&mut Writer
特征的對(duì)象。這在理論上非常好,但是當(dāng)被帶回實(shí)施時(shí)就會(huì)倒塌。當(dāng)涉及到約束時(shí),默認(rèn)情況下它們是大小的,因此它會(huì)抱怨,Writer
您嘗試分配的值W
不是大小。
這里有兩個(gè)主要解決方案:
切換到使用具體的編寫器類型,
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) }}
允許
W
成為未定義的類型。這是可以接受的,因?yàn)槟荒芡ㄟ^引用使用它&mut W
。如果您希望將其用作裸型,例如W
按價(jià)值計(jì)算的方法,則不會(huì)這樣做。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) }}
我會(huì)建議支持一個(gè)unsized,W
即使你沒有在這種情況下使用它 - 沒有理由它需要大小。
添加回答
舉報(bào)