In Rost, was ist der Unterschied zwischen clone() und to_owned()?
In Rust Clone
ist eine Eigenschaft, die angibt, wie clone
Methode (und clone_from
). Einige Merkmale, wie StrSlice
und CloneableVector
angeben to_owned
fn. Warum würde eine Umsetzung benötigen die beiden? Was ist der Unterschied?
Ich ein experiment mit Rost-strings, die haben beide Methoden, und es zeigt, dass es einen Unterschied gibt, aber ich verstehe es nicht:
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);
}
Compile-Zeit-Fehler für die to_owned
Beispiel:
error: mismatched types: expected `~str` but found `&'static str`
(str storage differs: expected `~` but found `&'static `)
clone.rs:30 println!("{:?}", c1 == s1);
Warum würde das erste Beispiel arbeiten, aber nicht die zweite?
- Dieser Fehler ist nicht reproduzierbar mehr in der aktuellen Rost (siehe in der Spielplatz, wo ich ersetzt
~"abc"
mit"abc".to_string()
- Ich aktualisierte das Beispiel zu verwenden
to_string()
eher als die älteren ' ~ ' - notation. Es ist jedoch interessant, dass diese neue version (Ihr Eintrag) jetzt kompiliert und läuft einwandfrei. Hat eine änderung der==
Betreiber/fn passieren, damit Sie vergleichen können&str
undString
- Typen für den Wert der Gleichheit?
Du musst angemeldet sein, um einen Kommentar abzugeben.
.clone()
gibt seinen Empfänger.clone()
auf eine&str
gibt eine&str
. Wenn Sie möchten, eineString
benötigen Sie eine andere Methode, die in diesem Fall ist.to_owned()
.Für die meisten Arten,
clone()
ist ausreichend, da es nur auf den zugrunde liegenden Typ und nicht der Typ der Referenz. Aber fürstr
und[T]
,clone()
umgesetzt wird, auf den Referenz-Typ (&str
und&[T]
), und es hat daher der falsche Typ. Es ist auch implementiert auf dem eigenen Typen (String
undVec<T>
), und in diesem Fallclone()
zurückkehren wird, ein anderes im Besitz Wert.Deinem ersten Beispiel funktioniert, weil
c1
unds1
(undc2
unds2
) haben die gleichen Typen. Dein zweites Beispiel nicht, weil Sie nicht (c1
istString
in der Erwägung, dasss1
ist&str
). Das ist ein perfektes Beispiel dafür, warum die getrennte Methoden sind notwendig.Als der aktuelle Rost, beide jetzt kompilieren, aber in
test_clone()
c1
ist einString
und intest_to_owned()
es ist ein&str
. Ich bin mir ziemlich sicher, dass es kompiliert Rost ist jetzt mehr nachsichtig über automatisch Referenzierung und Dereferenzierung Werte. In diesem Beispiel glaube ich, dass diec1 == s1
Zeile kompiliert wird, als ob es sagte&*c1 == s1
. Wenn Sie möchten, zu beweisen, dass die Arten beteiligt, die Sie hinzufügen können, eine bewusste Art Fehler, wielet _: i32 = c1;
und die Fehlermeldung zeigt die Art.c1 == s1
ich denke, dass endet zusammengestellt als&*c1 == s1
, das ist ein&str == &str
Vergleich. Beachten Sie, dassc1
imtest_to_owned()
Beispiel ist immer noch einString
.