You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Rust中.to_owned()、.clone()与解引用(*)的差异探究

Rust中to_owned()、clone()和解引用*对数组切片的克隆差异

先看你的代码和输出:

fn main() {
    let a = &[1, 2, 3];
    
    let mut o = a.to_owned();
    let mut c = a.clone();
    let mut d = *a;
    
    o[0] = 7;
    c[0] = 8;
    d[0] = 9;
    
    println!("o: {:?}", o);
    println!("c: {:?}", c);
    println!("d: {:?}", d);
    println!("a: {:?}", a);
}

输出:

o: [7, 2, 3]
c: [8, 2, 3]
d: [9, 2, 3]
a: [1, 2, 3]

三者表面上都复制了a的内容,但类型和内存分配逻辑完全不同:

1. a.to_owned() → Vec<i32>

to_owned()是ToOwned trait的方法,这里a会被自动强制转换为切片&[i32],对应的实现会在堆上分配内存,把切片元素复制进去,返回一个动态增长的Vec<i32>。

  • 特点:可以随时调用push/pop调整长度,内存分配在堆上,生命周期由所有权系统管理。

2. a.clone() → [i32; 3]

Rust方法调用会自动解引用,所以a.clone()等价于(*a).clone()。a的实际类型是&[i32; 3](固定大小数组的引用),而[i32; 3]实现了Clone trait,克隆后返回一个栈分配的固定大小数组。

  • 特点:长度固定,无法动态增减元素,内存分配在栈上,性能更高但受栈大小限制。

3. *a → [i32; 3]

直接解引用a会得到底层的固定大小数组[i32; 3],因为i32实现了Copy trait,数组也自动实现Copy,所以这是一次值拷贝。

  • 特点:和clone()的结果类型完全一致,都是栈上的固定大小数组,本质是直接复制值,无需调用clone方法,更简洁。

直观验证差异的例子

给o(向量)添加元素是合法的:

o.push(4); // 正常运行,o变为[7,2,3,4]

但给c或d(固定数组)添加元素会直接编译错误:

c.push(4); // 编译错误:数组没有`push`方法

打印类型也能直观看到区别:

println!("o的类型:{}", std::any::type_name::<_>(&o)); // Vec<i32>
println!("c的类型:{}", std::any::type_name::<_>(&c)); // [i32; 3]
println!("d的类型:{}", std::any::type_name::<_>(&d)); // [i32; 3]

内容的提问来源于stack exchange,提问作者fadedbee

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.14 20:15:41