我一直在学习Ruust,我也一直在努力学习借阅判断器的工作原理,但我遇到了这两个例子,我不明白为什么只有一个被认为是借来的:

fn main() {
    let mut x = String::from("aa ab");

    let y = first_word(&x);

    x.clear(); //Error cannot borrow X

    println!("{y}");


}

//Returns an i32 reference
fn first_word(s: &String) -> &i32 {
    return &32;
}   
fn main() {
    let mut x = String::from("aa ab");

    let y = first_word(&x);

    x.clear(); //Everything is fine

    println!("{y}");


}

//Returns an i32
fn first_word(s: &String) -> i32 {
    return 32;
}   

有没有人可以解释一下为什么只有第二种方法有效?

推荐答案

铁 rust 不会研究它们的功能,以了解它们在外部是如何工作的.函数签名必须包含所有必要的信息.

签名fn first_word(s: &String) -> &i32说"引用一个字符串"(顺便说一句,&String实际上从来没有用过,总是用&str代替),并返回一个对int的引用.但铁 rust 也需要生命周期 信息,即关于引用背后的东西的生命周期 的一些界限.

这是一个非常简单的过程,称为lifetime elision.对于"获取引用,返回引用",合理的假设是,返回的任何内容都与传入的内容有某种关联,因此完整的签名成为fn first_word<'a>(s: &'a String) -> &'a i32.

这意味着,当编译器看到对first_word的调用时,它将假定只要您保留返回的引用(代码中的y),传入的东西仍然是borrow 的.

Rust相关问答推荐

如何在不安全的代码中初始化枚举 struct

如何优化小型固定大小数组中的搜索?

如何将元素添加到向量并返回对该元素的引用?

MacOS(AARCH64)上Ghidra中的二进制补丁导致进程终止

如何将像烫手山芋一样不透明的值从一个Enum构造函数移动到下一个构造函数?

Tokio_Postgres行上未显示退回特性的生存期,且生命周期 不够长

Pin<;&;mut可能将Uninit<;T>;>;合并为Pin<;&;mut T>;

我可以在不收集或克隆的情况下,将一个带有Item=(key,val)的迭代器拆分成单独的key iter和val iter吗?

我们能确定Rust会优化掉Clone()吗?如果它会立即掉落?

在铁 rust 中,如何一次只引用几件事中的一件?

在运行特定测试时,如何 suppress cargo test 的空输出?

Rust从关联函数启动线程

try 实现线程安全的缓存

如何强制匹配的返回类型为()?

将引用移动到线程中

如何获取模块树?

Rust 中的方法调用有什么区别?

如何将参数传递给Rust 的线程?

如何获得对数组子集的工作可变引用?

在 Traits 函数中设置生命周期的问题