rustgo

81 阅读3分钟

1.字符串: 在Go语言中,字符串是不可变的,它们的值在创建后不能被改变。字符串由两部分组成:一个指向数据的指针和一个长度。这两部分都存储在栈上。 当你在Go中复制一个字符串,实际上复制的是指向数据的指针和长度,而不是数据本身。这意味着新旧两个字符串会共享同一份数据,这份数据通常在创建字符串时被分配在堆上。 例如,如果你有一个字符串s1,并且你创建了一个新的字符串s2 = s1,那么s1和s2都会指向同一份数据。如果你修改s2(例如,通过s2 += " world"),Go会创建一个新的字符串来存储修改后的值,而原始的s1不会被改变。 所以,对于Go语言中的字符串,复制操作是在栈上进行的,但复制的是指向堆上数据的引用。

对于基本类型(如int,float,bool等)和结构体,当你将一个变量赋值给另一个变量时,Go会在栈上创建一个新的副本。 对于引用类型(如切片,映射,通道,接口和函数类型)以及数组和结构体中包含这些类型的字段,变量赋值会复制引用,而不是底层数据。这意味着新旧两个变量将共享同一份底层数据,这些数据通常在堆上。 例如,如果你有一个切片a,并且你创建了一个新的切片b = a,那么a和b都会指向同一份底层的数组数据。如果你修改b,a也会受到影响,因为它们共享同一份数据。 总的来说,Go语言中的复制行为取决于数据的类型。对于值类型,复制会在栈上进行,对于引用类型,复制引用通常会在堆上进行。

rust: 在Rust中,String类型的数据存储在堆上。当你创建一个新的String,Rust会在堆上分配足够的空间来存储字符串的内容。这允许String动态地增长和缩小。 当你将一个String赋值给另一个String时,Rust默认会移动所有权,而不是复制数据。这意味着原始的String不能再被使用,因为它的所有权已经被移动到新的String了。 如果你想要复制一个String,你可以使用clone方法。这会创建一个新的String,并复制原始String的内容到新的String。这个操作会在堆上进行,因为String的数据是存储在堆上的。

let s1 = String::from("hello");
let s2 = s1; // s1失效
println!("s2 = {}", s2);

对于固定类型的的case:
let x = 5;
let y = x;

这段代码并没有发生所有权的转移,原因很简单: 代码首先将 5 绑定到变量 x,接着拷贝 x 的值赋给 y,最终 x 和 y 都等于 5,因为整数是 Rust 基本数据类型,是固定大小的简单值,因此这两个值都是通过自动拷贝的方式来赋值的,都被存在栈中,完全无需在堆上分配内存。 整个过程中的赋值都是通过值拷贝的方式完成(发生在栈中),因此并不需要所有权转移。

枚举类型
检测是否为None:
enum Option<T> {
    None,
    Some(T),
}

用 Result 处理可恢复的错误
enum Result<T, E> {
    Ok(T),
    Err(E),
}