代码之家  ›  专栏  ›  技术社区  ›  Kayote

除了非文字进入堆之外,文字和非文字之间的区别是什么?

  •  2
  • Kayote  · 技术社区  · 7 年前

    我对文本和非文本(堆上的那些,我不知道它们叫什么)之间的区别感到困惑。例如 taking the String type as an example :

    我们已经看到了字符串文字,其中字符串值是硬编码的 加入我们的计划。字符串文字很方便,但它们不是 始终适用于您想要使用文本的每种情况。一 原因是它们是不可变的。。。

    我不理解上述内容,因为我们已经看到了这样一个例子:

    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?
    

    显然,字面值在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");
    
    1 回复  |  直到 7 年前
        1
  •  15
  •   Shepmaster Tim Diekmann    7 年前

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

    首先,你需要理解 what a literal is . 文字是 从不 因为它们是可变的 字面上 用源代码编写并编译成最终二进制。您的程序不会更改源代码!

    显示无法修改文本的示例:

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

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

    fn main() {
        let mut a = 1;
        a += 2;
    }
    

    老实说,我不知道我会称之为“非文字”。文字是 表示 ,但除了表达式之外,程序中还有其他类型的内容。这有点像说“猫”和“非猫”,第二组包括狗、蘑菇、沙子和/或情绪吗?


    文字进入堆栈,而非文字进入堆

    这两种品质实际上没有直接关系。堆栈上很容易有非文本:

    fn main() {
        let a = 1;
        let b = 2;
        let c = a + b;
    }
    

    这三个变量都在堆栈上,但没有文本 3 源代码中的任何位置。

    目前,Rust不允许对文本值进行堆分配,但这是一种特定于语言的东西,可能会随着时间的推移而改变。其他语言可能允许这样做。

    事实上,你必须在铁锈中竭尽全力才能把东西堆起来。类型如下 Box , Vec String 所有调用函数在堆上分配空间。代码使用堆内存的唯一方法是使用这些类型、使用它们的其他类型或以其他方式分配堆内存的类型。


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

    没有 一串 文字无。源代码 "foo" 创建类型为的文本 &'static str . These are drastically different types . 具体来说,Rust语言可以在以下环境中工作 没有堆 ; 没有文字可以假定它可以分配内存。

    必须特别使用 String::from()

    String::from 转换自 &str 到a 一串 ; 它们是两种不同的类型,必须进行转换。

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

    ,他们不能。一开始是不可能的 let mut foo = "a" 并将“a”修改为其他任何内容。你 可以 改变什么 foo 指向:

    let mut foo = "a";
    
                    foo
         +-----------+
         |
         |
     +---v---+              
     |       |              
     |  "a"  |           
     |       |     
     +-------+         
    
    foo = "b";
    
                      foo
                       +----------+
                                  |
                                  |
       +-------+              +---v---+
       |       |              |       |
       |  "a"  |              |  "b"  |
       |       |              |       |
       +-------+              +-------+
    

    也不 "a" 也没有 "b" 千变万化 ,但是什么 foo公司 指向 .

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


    另请参见: