首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >在Rust中,clone()和to_owned()有什么不同?

在Rust中,clone()和to_owned()有什么不同?
EN

Stack Overflow用户
提问于 2014-03-08 11:09:52
回答 1查看 26.9K关注 0票数 77

在Rust中,Clone是指定clone方法(和clone_from)的特征。一些性状,如StrSliceCloneableVector,指定了to_owned fn。为什么一个实现需要这两者?有什么关系?

我用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);

为什么第一个例子可以工作,而第二个不行?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2014-03-08 14:06:37

.clone()返回它的接收器。&str上的clone()返回一个&str。如果需要String,则需要一个不同的方法,在本例中为.to_owned()

对于大多数类型,clone()就足够了,因为它只在底层类型上定义,而不是在引用类型上定义。但是对于str[T]clone()是在引用类型(&str&[T])上实现的,因此它的类型是错误的。它还在拥有的类型(StringVec<T>)上实现,在这种情况下,clone()将返回另一个拥有的值。

第一个示例之所以有效,是因为c1s1 (以及c2s2)具有相同的类型。您的第二个示例失败了,因为它们不是这样(c1String,而s1&str)。这是一个很好的例子,说明了为什么分离的方法是必要的。

到目前为止,两者都可以编译,但在test_clone()中,c1String,在test_to_owned()中是&str。我非常确定它的编译方式是Rust现在在自动引用和取消引用值方面更加宽松。在这个特定的例子中,我相信c1 == s1代码行被编译得就像&*c1 == s1一样。如果您希望证明所涉及的类型,您可以添加一个故意的类型错误,例如let _: i32 = c1;,错误消息将显示该类型。

票数 65
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/22264502

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档