在 Rust 中,Clone
是一个特征,它指定了 clone
方法(和 clone_from
)。一些特征,如 StrSlice
和 CloneableVector
指定一个 to_owned
fn。为什么实现需要两者?有什么区别?
我用 Rust strings 做了一个实验,它有两种方法,它证明是有区别的,但我不明白:
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);
为什么第一个示例有效而第二个示例无效?
最佳答案
.clone()
返回它的接收器。 clone()
在 &str
上返回 &str
.如果你想要 String
, 你需要一个不同的方法,在本例中是 .to_owned()
.
对于大多数类型,clone()
就足够了,因为它只在基础类型上定义,而不是在引用类型上定义。但是对于 str
和 [T]
, clone()
在引用类型( &str
和 &[T]
)上实现,因此它的类型错误。它也在拥有的类型( String
和 Vec<T>
)上实现,在这种情况下是 clone()
将返回另一个拥有的值。
您的第一个示例之所以有效,是因为 c1
和 s1
(以及 c2
和 s2
)具有相同的类型。你的第二个例子失败了,因为它们没有( c1
是 String
而 s1
是 &str
)。这是为什么需要单独的方法的完美示例。
从当前的 Rust 开始,两者现在都可以编译,但在 test_clone()
中c1
是 &str
在test_to_owned()
这是一个String
.我很确定它可以编译,因为 Rust 现在对自动引用和取消引用值更加宽松。在这个特定的例子中,我相信 c1 == s1
行被编译为好像它说 &*c1 == s1
.如果你想证明所涉及的类型,你可以添加一个故意的类型错误,例如 let _: i32 = c1;
错误消息将显示类型。
关于rust - 在 Rust 中,clone() 和 to_owned() 有什么区别?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22264502/