String slices的生命周期

huangapple go评论74阅读模式
英文:

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

这是一个被称为变量遮蔽的概念。每当你使用 letlet 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

huangapple
  • 本文由 发表于 2023年6月9日 04:50:52
  • 转载请务必保留本文链接:https://go.coder-hub.com/76435602.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定