2016-06-17 4 views
6

以下のコードがコンパイルされ、正常に動作:なぜRustは変数が&strであることを認識しませんか?

use std::fmt::Display; 

fn display(x: &str) { 
    println!("{}", x); 
} 

fn main() { 
    let s: &str = "hi there"; 
    display(s); 
} 

あなたは

fn display(x: &Display) 

するdisplay機能を変更した場合しかし、それは次のエラー与える:display(s)を変更することにより

src/main.rs:9:13: 9:14 error: the trait `core::marker::Sized` is not implemented for the type `str` [E0277] 
src/main.rs:9  display(s); 

display(&s)に戻ります。

ここでは何が起こっていますか?明らかに型は&strですが、&Displayが入力引数である場合、その型は認識されません。

注:&34も引数として有効です。これはDisplayが実際に&strに実装されていて、strでは実装されていないためですか?

答えて

6

として真である&s: &Display =>&(&str) : &Displayを期待しています。

さび1.9(これを変更なし現在の計画)のまだ

タイプT「がSized」である場合、形質オブジェクトへの変換は、&Traitから&Tに対してのみ可能です。

理由は実装です。&Displayのような形質オブジェクトは、データへのポインタと形質メソッドのテーブルへのポインタ(vtable)の2つのフィールドで構成されています。この表現は、参照が「薄い」つまり正確にタイプがwhere T: Sizedの値に対してのみ可能です。 A &strは「太い」参照であり、ポインタと長さを持つため、strは特性オブジェクトのデータにはなりません。正確


Why does display(&s) work though? I guess that is a referene to the "fat" reference?

はい、。 A &&strは、&str値の変数を指す「シン」参照です。したがって、&Displayに変換することができます。

+1

なぜ 'display(&s)'は動作しますか?私はそれが "脂肪"参照へのレフェリーだと思いますか? "fat"参照型か、何らかの理由で '&str'型である他の型がありますか? – vitiral

+1

私はなぜ 'str'が'&str'の代わりにデータと長さを持つ構造体ではないのか分かりません。それで '&str'はもはや太ったポインタにならなくなり、この問題は起こりません! – vitiral

+1

私はファットポインターを見て、これはかなり良いリファレンスでした:https://www.reddit.com/r/rust/comments/38tv6n/when_is_a_reference_not_a_pointer/私は調査を続けます... – vitiral

5

(メインの答えに私の編集を推進)

あなたがfn display(x: &Display)を書くとき、関数はそれを逆参照することによりtrait objectに強制することができます値をとります。また、Rust関数は、コンパイル時にパラメータxの値のサイズを知る必要があります。

&34&u32タイプ)を逆参照して形質オブジェクトに強制変換すると、u32になり、そのサイズを決定できます。

&strを逆参照すると、strになり、文字列の長さは何でもかまいません。添加することにより

&&str&&str)に、それはポインタであり、その大きさを決定することができる、バック&strに逆参照されます。私はこれがなぜあなたのコード内でdisplay(&s)を受け入れるだけだと考えています。

+0

これは、そのコーディングが起こっています。おそらく主な回答にあなたの編集を促進する? –

+0

この度はありがとうございます。主な回答に私の編集を促進しました。 –

+0

本書では、「形質はこれらの両方が真であればオブジェクトセーフである:1)形質は「自己:サイズ」を必要とせず、2)すべての方法はオブジェクトセーフである」と述べている。 'Sized'値への参照のみを特性オブジェクトにキャストできます – aSpex

1

By changing display(s) to display(&s) it works again.

それはすべて

  • display(s)が偽s: &Display、=>&str: &Displayを期待(これは単なる表記で)&str: Display (+ Sized)str: !Displayにダウンしました。
  • display(&s)はあなたがタイプstrDisplayを実装しているので意味をなさないように思われ、(形質オブジェクトへの参照)&str&Displayに強制変換されなければならないことを要求している&str: Display
+0

'str'に対して' Display'が実装され、 '&str'に対しては実装されていません。 http://doc.rust-lang.org/src/core/up/src/libcore/fmt/mod.rs.html#1371-1375 – aSpex

関連する問題