文字和非文字有什么区别,除了非文字进入堆的事实?

Kay*_*ote 0 types memory-management rust

我对文字和非文字之间的区别感到困惑(那些在堆上的,我不知道它们被称为什么).例如,String类型为例:

我们已经看过字符串文字,其中字符串值被硬编码到我们的程序中.字符串文字很方便,但它们并不总是适合您想要使用文本的每种情况.一个原因是它们是不可改变的....

我不明白上面的内容,因为我们已经看到了这样一个例子:

let mut a = "a"; // this is String literal here, so sitting on the stack
a = "b";
println!("a is being changed to...{}", a); // this is the same String literal sitting on the stack?
Run Code Online (Sandbox Code Playgroud)

显然,文字在Rust中是可变的.两者之间有什么区别,除了文字进入堆栈这一事实,而非文字进入堆?

我试图理解为什么我不应该在我的代码中使用可变文字,考虑到堆栈比堆快.

// a is mutable literal
let mut a = "a";
a = "b";
// b is mutable 'non-literal'
let mut b = String::from("a");
b = String::from("b");
Run Code Online (Sandbox Code Playgroud)

She*_*ter 12

显然,文字在Rust中是可变的

首先,您需要了解文字是什么.文字永远不可变,因为它们字面上写在源代码中并编译成最终的二进制文件.您的程序不会更改您的源代码!

显示您无法修改文字的示例:

fn main() {
    1 += 2;
}
Run Code Online (Sandbox Code Playgroud)
error[E0067]: invalid left-hand side expression
 --> src/main.rs:2:5
  |
2 |     1 += 2;
  |     ^ invalid expression for left-hand side
Run Code Online (Sandbox Code Playgroud)

另一方面,可以将文字复制到变量中,然后可以更改变量,但我们仍然不会改变文字1:

fn main() {
    let mut a = 1;
    a += 2;
}
Run Code Online (Sandbox Code Playgroud)

说实话,我不知道我称之为"非文字".文字是特定类型的表达式,但除了表达式之外,程序中还有其他类型的事物.这有点像说"猫"和"非猫" - 第二组是否包括狗,蘑菇,沙子和/或情感?


文字进入堆栈的事实,而非文字进入堆

这两个品质并没有真正直接相关.在堆栈上使用非文字非常容易:

fn main() {
    let a = 1;
    let b = 2;
    let c = a + b;
}
Run Code Online (Sandbox Code Playgroud)

所有三个变量都在堆栈中,但3源代码中没有任何文字.

现在,Rust不允许文字值具有堆分配,但这是特定于语言的事物,可能会随着时间的推移而发生变化.其他语言可能允许它.

事实上,你必须在Rust中走出困境才能把东西放在堆上.类似Box,VecString所有调用函数来在堆上分配空间.代码使用堆内存的唯一方法是使用这些类型,使用它们的其他类型,或以其他方式分配堆内存的类型.


我们不能使用String文字数据类型的原因是什么

没有String文字 - 没有.源代码"foo"创建一个类型的文字&'static str.这些是完全不同的类型.具体来说,Rust语言可以在没有堆的环境中工作; 没有文字可以假设可以分配内存.

必须专门使用 String::from()

String::from转换&str为a String; 它们是两种不同的类型,必须进行转换.

显然,根据示例,在我的代码中,两者都可以是可变的

,他们不能.不可能开始let mut foo = "a"并修改"a"以成为其他任何东西.您可以更改foo指向的内容:

let mut foo = "a";
Run Code Online (Sandbox Code Playgroud)
                foo
     +-----------+
     |
     |
 +---v---+              
 |       |              
 |  "a"  |           
 |       |     
 +-------+         
Run Code Online (Sandbox Code Playgroud)
foo = "b";
Run Code Online (Sandbox Code Playgroud)
                  foo
                   +----------+
                              |
                              |
   +-------+              +---v---+
   |       |              |       |
   |  "a"  |              |  "b"  |
   |       |              |       |
   +-------+              +-------+
Run Code Online (Sandbox Code Playgroud)

既不"a"也不"b" 曾改变,但什么foo指向.

不是Rust特有的.例如,Java和C#字符串也是不可变的,但您可以重新分配变量以指向不同的不可变字符串.


也可以看看:

  • @Kayote所谓的"字符串文字"不是`String`类型,而是类型`&'static str`:[这个问题有更多](/sf/ask/2600488201/的差 - 这些-3-方式-的-声明-A-字符串在防锈间). (3认同)