Rust では、clone() と to_owned() の違いは何ですか? 質問する

Rust では、clone() と to_owned() の違いは何ですか? 質問する

Rust では、はメソッド (および)Cloneを指定する特性です。 や などの一部の特性はfnを指定します。実装に両方が必要なのはなぜでしょうか。違いは何でしょうか。cloneclone_fromStrSliceCloneableVectorto_owned

両方の方法を備えた Rust 文字列で実験を行ったところ、違いがあることが示されましたが、理解できませんでした。

fn main() {
    test_clone();
    test_to_owned();
}

// compiles and runs fine    
fn test_clone() {
    let s1: &'static str = "I am static";
    let s2 = "I am boxed and owned".to_string();

    let c1 = s1.clone();
    let c2 = s2.clone();

    println!("{:?}", c1);
    println!("{:?}", c2);

    println!("{:?}", c1 == s1);  // prints true
    println!("{:?}", c2 == s2);  // prints true
}

fn test_to_owned() {
    let s1: &'static str = "I am static";
    let s2 = "I am boxed and owned".to_string();

    let c1 = s1.to_owned();
    let c2 = s2.to_owned();

    println!("{:?}", c1);
    println!("{:?}", c2);

    println!("{:?}", c1 == s1);   // compile-time error here (see below)
    println!("{:?}", c2 == s2);
}

この例のコンパイル時エラーは次のto_ownedとおりです。

error: mismatched types: expected `~str` but found `&'static str` 
(str storage differs: expected `~` but found `&'static `)
clone.rs:30     println!("{:?}", c1 == s1);

最初の例は機能するのに、2 番目の例は機能しないのはなぜでしょうか?

ベストアンサー1

.clone()はレシーバを返します。clone()は を&str返します&str。 が必要な場合はString、別のメソッド (この場合は ) が必要です.to_owned()

ほとんどの型の場合、clone()は基になる型でのみ定義され、参照型では定義されていないため、十分です。ただし、strおよび の場合、は参照型 (および) で実装されているため、型が間違っています。また、 は所有型 (および) で実装されているため、その場合は別の所有値を返します。[T]clone()&str&[T]StringVec<T>clone()

最初の例は、c1s1(およびc2s2) が同じ型であるため機能します。2 番目の例は、同じ型ではないため (c1Stringあるのに対しs1&str)、機能しません。これは、別々のメソッドが必要である理由を示す完璧な例です。


現在の Rust では、どちらもコンパイルされますが、 は でtest_clone() c1&strは ですtest_to_owned()。RustStringは値の自動参照と逆参照に関してより寛容になったので、コンパイルされるのは間違いありません。この特定の例では、 のc1 == s1行は であるかのようにコンパイルされると思います&*c1 == s1。関係する型を証明したい場合は、 などの意図的な型エラーを追加できますlet _: i32 = c1;。エラー メッセージには型が表示されます。

おすすめ記事