MST

星途 面试题库

面试题:Rust普通结构体设计中的字段所有权问题

在Rust中设计一个包含字符串字段的普通结构体。阐述如何处理该字符串字段的所有权,避免内存泄漏或悬空指针问题。同时,写出结构体定义及一个使用该结构体的简单函数示例。
48.5万 热度难度
编程语言Rust

知识考点

AI 面试

面试题答案

一键面试

结构体定义及所有权处理

在Rust中,String类型拥有它所分配的内存的所有权。当String离开作用域时,其析构函数会自动释放内存,从而避免内存泄漏。对于包含String字段的结构体,同样遵循Rust的所有权规则。

// 定义包含字符串字段的结构体
struct MyStruct {
    my_string: String,
}

// 使用该结构体的简单函数
fn print_my_struct(s: MyStruct) {
    println!("The string is: {}", s.my_string);
}

解释

  1. 结构体定义
    • MyStruct结构体包含一个my_string字段,类型为StringString是Rust中可增长的、堆分配的字符串类型,它拥有其内部数据的所有权。
  2. 所有权转移
    • print_my_struct函数中,参数s通过值传递,这意味着s的所有权被转移到了函数内部。函数结束时,s离开作用域,其my_string字段所占用的内存会被自动释放,避免了内存泄漏和悬空指针问题。
  3. 避免悬空指针
    • Rust的所有权系统在编译时就会检查代码,确保所有指针都是有效的。如果试图在my_string已经被释放后访问它,编译器会报错,从而防止悬空指针问题。例如,下面的代码是不合法的:
// 以下代码会导致编译错误
fn main() {
    let s1 = MyStruct {
        my_string: String::from("hello"),
    };
    let s2 = s1; // s1的所有权转移给s2
    println!("{}", s1.my_string); // 这里访问s1会报错,因为s1已经失去了所有权
}

正确的做法是在let s2 = s1;之后,使用s2来访问字符串,如:

fn main() {
    let s1 = MyStruct {
        my_string: String::from("hello"),
    };
    let s2 = s1;
    println!("{}", s2.my_string);
}

这样可以确保在任何时候都不会出现悬空指针的情况。