ps4 - rust traduccion
En Rust, ¿cuál es la diferencia entre clone() y to_owned()? (1)
.clone()
devuelve su receptor. clone()
en a &str
devuelve a &str
. Si desea una String
, necesita un método diferente, que en este caso es .to_owned()
.
Para la mayoría de los tipos, clone()
es suficiente porque solo está definido en el tipo subyacente y no en el tipo de referencia. Pero para str
y [T]
, clone()
se implementa en el tipo de referencia ( &str
y &[T]
), y por lo tanto tiene el tipo incorrecto. También se implementa en los tipos de propiedad ( String
y Vec<T>
) y, en ese caso, clone()
devolverá otro valor de propiedad.
El primer ejemplo funciona porque c1
y s1
(y c2
y s2
) tienen los mismos tipos. El segundo ejemplo falla porque no lo hacen ( c1
es String
mientras que s1
es &str
). Ese es un ejemplo perfecto de por qué los métodos separados son necesarios.
En Rust, Clone
es un rasgo que especifica el método de clone
(y clone_from
). Algunos rasgos, como StrSlice
y CloneableVector
especifican un fn de to_owned
. ¿Por qué una implementación necesitaría ambos? ¿Cuál es la diferencia?
Hice un experimento con cuerdas Rust, que tienen ambos métodos, y demuestra que hay una diferencia, pero no lo entiendo:
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);
}
El error de tiempo de compilación para el ejemplo de to_owned
es:
error: mismatched types: expected `~str` but found `&''static str`
(str storage differs: expected `~` but found `&''static `)
clone.rs:30 println!("{:?}", c1 == s1);
¿Por qué funcionaría el primer ejemplo pero no el segundo?