为何Rust中do_something_else无需借用引用,新增函数却可能需要?
为什么Rust示例中两个函数不必都使用引用?
核心原因:Rust的所有权与借用规则
Rust的核心规则是每个值有且只有一个所有者,函数参数的传递方式直接决定了所有权的走向:
- 直接传值(比如
book: Book):会触发所有权转移,原变量在调用后就会失效,不能再被使用。 - 传递引用(比如
book: &Book):属于借用,只是临时获取值的访问权,所有权仍保留在原变量手中,调用后原变量依然可用。
示例代码的合理性分析
看你给出的示例:
struct Book { title: String } fn print_book(book: &Book) { println!("Book: {}", book.title); } fn do_something_else(book: Book) { println!("Again: {}", book.title); } fn main() { let book = Book { title: String::from("The Rust Programming Language") }; print_book(&book); do_something_else(book); }
print_book用引用:因为它只需要读取书名,不需要夺走所有权,调用后main里的book还能继续传给下一个函数。do_something_else直接传值:因为它是main中book的最后一次使用——调用完这个函数后,main里再也没用到book了,所以转移所有权完全没问题,没必要多此一举用引用。
新增函数后必须全用引用的原因
如果在main里,do_something_else之后还要调用第三个函数操作book,那原来的写法就会报错:
// 新增函数 fn update_book(book: &mut Book) { book.title.push_str(" (2nd Edition)"); } fn main() { let mut book = Book { title: String::from("The Rust Programming Language") }; print_book(&book); do_something_else(book); // 报错:book的所有权已转移给do_something_else,无法再使用 update_book(&mut book); }
这时候就必须让do_something_else也改用引用,这样所有权一直留在main的book变量里,所有函数都只是借用它:
fn do_something_else(book: &Book) { println!("Again: {}", book.title); } fn main() { let mut book = Book { title: String::from("The Rust Programming Language") }; print_book(&book); do_something_else(&book); update_book(&mut book); // 还能继续使用book print_book(&book); }
简单说就是:只要后续还要用到原变量,所有函数都必须用引用;如果某个函数是原变量的最后一次使用,那直接传值转移所有权是完全合法且合理的选择。
内容的提问来源于stack exchange,提问作者Shinomoto Asakura
相关产品推荐
相关产品推荐

