gpt4 book ai didi

rust - 为什么返回一个字符串切片而不是一个 usize 会阻止改变一个字符串?

转载 作者:行者123 更新时间:2023-11-29 08:22:05 26 4
gpt4 key购买 nike

此代码编译:

fn main() {
let mut s = String::from("some_string");
let n = f1(&s);
s.clear();
println!("n = {}", n);
}

fn f1(s: &String) -> usize {
10
}

fn f2(s: &String) -> &str {
"def"
}

但是,将对 f1() 的调用替换为 f2() 会导致编译失败。在我看来,f1()f2() 都进行了不可变借用,而 s.clear() 进行了可变借用,所以在这两种情况下我都应该得到编译错误。我错过了什么?

最佳答案

这是重现问题所需的最少代码:

fn f1(s: &String) -> usize { unimplemented!() }

fn f2(s: &String) -> &str { unimplemented!() }

fn main() {
let mut s = String::from("some_string");
let n = f1(&s);
s.clear();
println!("n = {}", n);
}

根据函数签名执行生命周期分析。

你会注意到在上面的代码中我使用了unimplemented!()作为函数体,问题是完全一样的。这是正常

在绝大多数情况下1,一个函数签名完全指定了一个函数的接口(interface),没有必要去查看它的实现。

作为推论,这也意味着返回类型中的生命周期是否链接到任何参数中的生命周期在签名中完全指定,在这种情况下,f2 的完整签名> 因此:

fn f2<'a>(s: &'a String) -> &'a str;

f2 的实现是"def"(具有'static 生命周期)还是&*s (与 'a 生命周期)无关紧要;只有签名很重要,并且由于省略规则,签名使用相同的生命周期。

1 我所知道的一个异常涉及 -> impl Trait 特性以及结果对象是否实现了 Send同步


f1 的情况下,返回类型没有链接到参数,因此参数的借用在 f1 调用结束时结束:

fn main() {
let mut s = String::from("some_string");
let n = {
// Immutable borrow of s starts here.
f1(&s)
// Immutable borrow of s ends here.
};
s.clear();
println!("n = {}", n);
}

f2 的情况下,返回类型与参数具有相同的生命周期,因此被认为是对借用的扩展。在 Rust 2015 中,借用会一直持续到返回值超出范围(词法借用);在 Rust 2018 中,借用一直延伸到返回值的最后一次使用(非词法借用)。

在您的情况下,两者基本相同:

fn main() {
let mut s = String::from("some_string");
let n = {
// Immutable borrow of s starts here.
f2(&s)
};
s.clear(); // Conflicting attempt to mutably borrow s.
println!("n = {}", n);
// Immutable borrow of s ends here.
}

您可以通过调换 s.clear()println! 的顺序来观察差异。

关于rust - 为什么返回一个字符串切片而不是一个 usize 会阻止改变一个字符串?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56383628/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com