英文:
Lifetimes for String slices
问题
I'm going through the rust black book and it mentions lifetime elision rules, and how especially for functions inputting and returning &str (strings stored on the stack), don't need explicit lifetimes. My question is why did they do so in the first place. The way I've been visualizing a string in rust is somewhat like a slice that the variable now holds. Is that incorrect?
这本书提到了生命周期省略规则,尤其是对于输入和返回的 &str(存储在堆栈上的字符串),不需要显式的生命周期。我的问题是,为什么他们一开始就这样做呢?我一直将 Rust 中的字符串视为变量现在持有的切片,这种看法是否不正确?
let mut s = String::from("alfdj");
let k = &s[0..1];
let s = "laskjd";
println!("{}", k);
这是我尝试的内容,也是让我感到困惑的字符串 s 和切片 k 之间的关系。我重新定义了 s,但它对 k 没有影响,这就是我认为 &str k 变得独立于字符串 s 的原因。
英文:
I'm going through the rust black book and it mentions lifetime elision rules, and how especially for functions inputting and returning &str (strings stored on the stack), don't need explicit lifetimes. My question is why did they do so in the first place. The way I've been visualizing a string in rust is somewhat like a slice that the variable now holds. Is that incorrect?
let mut s = String::from("alfdj");
let k = &s[0..1];
let s = "laskjd";
println!("{}",k);`
This is what I tried and what confused me about the relationship between the string s and the slice k. I redefine s and it has no effect on k which is why I thought the &str k became independent of the string s.
答案1
得分: 0
这是一个被称为变量遮蔽的概念。每当你使用 let
或 let mut
定义一个变量时,你实际上创建了一个新的变量,它恰好具有相同的变量名。旧变量仍然存在,但不能通过其名称访问。这是词法作用域概念的一部分。你的代码片段等效于以下内容:
let mut s = String::from("alfdj");
let k = &s[0..1];
let w = "laskjd";
println!("{}", k);
在这里,我们只是将第二个 s
替换为 w
。
当你调用函数时也会发生同样的情况。例如,在以下代码中:
fn scoping() -> i32 {
let x = 3;
let g = |mut x| {
x += 1;
x
};
g(x) + x // 计算结果为7;调用g(x)不会改变x
}
有两个不同的变量,都命名为 x
。同样地,我们可以有以下情况发生:
let x = 3;
{
let x = 4;
println!("{}", x); // 4
let x = "abc";
println!("{}", x); // abc
}
println!("{}", x); // 3
英文:
This is a concept known as variable shadowing. Whenever you define a variable using let
or let mut
, you are creating a new variable which happens to have the same variable name. The old variable still exists but cannot be accessed through its name. This is part of the notion of lexical scoping. Your code snippet is equivalent to the following:
let mut s = String::from("alfdj");
let k = &s[0..1];
let w = "laskjd";
println!("{}",k);
Here, we just replaced the second s
with w
.
The same thing happens when you call a function. For example, in the code
fn scoping() -> i32 {
let x = 3;
let g = |mut x| {
x += 1;
x
};
g(x) + x // evaluates to 7; calling g(x) doesn't change x
}
there are two different variables, both named x
. Similarly, we can have the following occur:
let x = 3;
{
let x = 4;
println!("{}", x); // 4
let x = "abc";
println!("{}", x); // abc
}
println!("{}", x); // 3
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论