Rust 初体验2

变量类型

Rust 语言的变量数据类型,主要包括整型、浮点型、字符、布尔型、元组、数组、字符串、枚举、结构体和可变变量等。

rust 复制代码
fn main() {  
    // 整型  
    let integer: i32 = 100;  
    println!("整型: {}", integer);  
  
    // 浮点型  
    let floating_point: f64 = 3.14;  
    println!("浮点型: {}", floating_point);  
  
    // 字符  
    let character: char = 'A';  
    println!("字符: {}", character);  
  
    // 布尔型  
    let boolean: bool = true;  
    println!("布尔型: {}", boolean);  
  
    // 字符串  
    let string: String = String::from("Hello, Rust!");  
    println!("字符串: {}", string);  
  
    // 数组  
    let array: [i32; 5] = [1, 2, 3, 4, 5];  
    println!("数组: {:?}", array);  
  
    // 元组  
    let tuple: (i32, f64, String) = (10, 2.5, String::from("tuple"));  
    println!("元组: {:?}", tuple);  
  
    // 枚举  
    #[derive(Debug)]
    enum Color {  
        Red,  
        Green,  
        Blue
    }  
    let color: Color = Color::Red;  
    println!("枚举: {:?}", color);  
  
    // 结构体
    #[derive(Debug)]  
    struct Person {  
        name: String,  
        age: u32  
    }  
    let person: Person = Person {  
        name: String::from("Alice"),  
        age: 30  
    };  
    println!("结构体: {:?}", person);  
  
    // 可变变量  
    let mut mutable_variable = 10;  
    mutable_variable = 20;  
    println!("可变变量: {}", mutable_variable);  
}

所有权

Rust中每个值都有一个所有者。Rust 确保在变量离开作用域时值被清理。

rust 复制代码
fn main() {  
    let s1 = String::from("hello");  
    let s2 = s1;    // s1 的所有权转移到 s2,s1 不再有效
    println!("{}, world!", s2);  // Ok
    println!("{}, world!", s1);  // Error
}

这一点与C语言不同,C语言中 s1 的值被复制到 s2 中,s1仍然有效。

C 复制代码
#include <stdio.h>
int main() {  
    char* s1 = "hello";   
    char* s2 = s1;          // s1 的所有权转移到 s2,s1 不再有效
    printf("%s\n", s2);     // Ok
    printf("%s\n", s1);     // OK
    return 0;
}

Rust 中的变量分为两种:栈变量、堆变量。

栈变量存储在栈上,堆变量存储在堆上。栈变量的大小是固定的,而堆变量的大小是不固定的,需要动态分配内存。

Rust 中的变量默认存储在栈上,如果需要存储在堆上,可以使用 Box<T> 类型。

  • 栈(Stack):局部变量、函数参数和函数返回值通常存储在栈上。这些变量具有明确的生命周期,通常与它们所在的作用域相关。当变量离开其作用域时,它们的内存会被自动释放。

  • 堆(Heap):动态分配的数据,如使用Box、String、Vec等类型创建的变量,通常存储在堆上。这些变量具有更长的生命周期,并且由 Rust 的垃圾回收器管理。当没有任何引用指向堆上的数据时,垃圾回收器会释放该内存。

  • 静态存储区:静态变量和常量存储在静态存储区。这些变量的生命周期是整个程序的执行期间,它们在程序开始执行时就被分配,并在程序结束时才被释放。

在 Rust 中,变量的内存存储方式主要受到它们的数据类型和所有权规则的影响。在前面的 Rust 代码中,s1 和 s2 都是 String 类型的变量,这意味着它们存储的是对堆上分配的字符串数据的引用。
有效 栈:s1 堆:'hello'

图 1 图1 图1

当 s1 被创建时,Rust 会在堆上分配内存来存储字符串 "hello",并将一个引用(指针)赋值给 s1。这个引用包含了指向堆上数据的地址信息。
悬空 有效 栈:s1 由Rust回收 栈:s2 堆:'hello'

图 2 图2 图2

当 s2 被创建并赋值为 s1 时,根据 Rust 的所有权转移规则, s2 现在拥有了原来 s1 所拥有的数据的所有权。此时,s1 不再拥有对这块内存的所有权,它变成了一个悬空引用(dangling reference),指向一个不再有效的内存地址。

在 图2 中,s1 悬空。s2 指向了堆上存储的字符串 "hello"。当 s2 离开作用域并被销毁时,Rust 垃圾回收机制会确保释放这块堆上分配的内存。

在Rust中,变量本身通常存储在栈上(对于局部变量),而它们指向的数据(对于堆上分配的类型)则存储在堆上。所有权转移确保了当引用离开作用域时,相关的内存能够被正确地释放,从而避免了内存泄漏。

为什么要有这种机制?

Rust中的变量都是通过所有权(ownership)来管理的,当一个变量离开其作用域时,其占用的内存将被释放。这样可以避免内存泄漏和悬空指针的问题。

内存泄漏的主要原因是在程序中分配内存,但忘记释放它。Rust中的变量在离开作用域时会自动释放其占用的内存,因此不会发生内存泄漏。

悬空指针是指一个指针指向的内存已经被释放,但指针仍然指向该内存地址。悬空指针会导致程序崩溃或产生其他错误。在Rust中,变量在离开作用域时会自动释放其占用的内存,因此不会发生悬空指针的问题。

当然,安全性和灵活性之间需要进行权衡。在某些情况下,手动管理内存可以减少内存分配和释放的开销,从而提高程序的性能。但在其他情况下,Rust的自动内存管理可能会导致额外的开销和复杂性。因此,需要根据具体情况进行选择。

相关推荐
DongLi012 天前
rustlings 学习笔记 -- exercises/05_vecs
rust
番茄灭世神3 天前
Rust学习笔记第2篇
rust·编程语言
shimly1234563 天前
(done) 速通 rustlings(20) 错误处理1 --- 不涉及Traits
rust
shimly1234563 天前
(done) 速通 rustlings(19) Option
rust
@atweiwei3 天前
rust所有权机制详解
开发语言·数据结构·后端·rust·内存·所有权
shimly1234563 天前
(done) 速通 rustlings(24) 错误处理2 --- 涉及Traits
rust
shimly1234563 天前
(done) 速通 rustlings(23) 特性 Traits
rust
shimly1234563 天前
(done) 速通 rustlings(17) 哈希表
rust
shimly1234563 天前
(done) 速通 rustlings(15) 字符串
rust
shimly1234563 天前
(done) 速通 rustlings(22) 泛型
rust