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

2024-01-02

我对文字和非文字之间的区别感到困惑(那些在堆上的文字,我不知道它们叫什么)。例如,采取String键入作为示例 https://doc.rust-lang.org/book/second-edition/ch04-01-what-is-ownership.html#the-string-type:

我们已经见过字符串文字,其中字符串值是硬编码的 进入我们的程序。字符串文字很方便,但事实并非如此 始终适合您想要使用文本的每种情况。一 原因是它们是不可变的。 ...

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

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");

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

首先,你需要了解what字面量是 https://stackoverflow.com/q/485119/155423。文字是never可变的,因为它们是字面上地编写在源代码中并编译成最终的二进制文件。您的程序不会更改您的源代码!

显示不能修改文字的示例:

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

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

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

说实话,我不知道什么叫“非字面”。文字是一种特定类型表达,但是程序中除了表达式之外还有其他类型的东西。这有点像说“猫”和“非猫”——第二组包括狗、蘑菇、沙子和/或情感吗?


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

这两个品质并不真正直接相关。在堆栈上放置非文字非常容易:

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

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

目前,Rust 不允许对文字值进行堆分配,但这是特定于语言的事情,可能会随着时间的推移而改变。其他语言可能允许它。

事实上,在 Rust 中你必须不遗余力地将一些东西放入堆中。类型如Box, Vec, and String所有调用函数在堆上分配空间。代码使用堆内存的唯一方法是使用这些类型、使用它们的其他类型或以其他方式分配堆内存的类型。


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

没有String字面意思——没有。源代码"foo"创建类型的文字&'static str. 这些是截然不同的类型 https://stackoverflow.com/q/24158114/155423。具体来说,Rust 语言可以在以下环境中工作:没有堆;没有文字可以假设可以分配内存。

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

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

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

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

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

Neither "a" nor "b" 永远改变,但是什么foo指着does.

This 不是 Rust 特有的。例如,Java 和 C# 字符串也是不可变的,但您可以reassign指向不同的不可变字符串的变量。


也可以看看:

  • “字面意思”这个词是什么意思? https://stackoverflow.com/q/485119/155423
  • 变量名前面的“mut”和“:”后面的“mut”有什么区别? https://stackoverflow.com/q/28587698/155423
  • Rust 的 `String` 和 `str` 有什么区别? https://stackoverflow.com/q/24158114/155423
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

除了非文字进入堆之外,文字和非文字之间有什么区别? 的相关文章

  • mysql_query 保留返回时在表中创建的数据类型?

    我在mysql中有一个表 CREATE TABLE user id INT name VARCHAR 250 我查询表 result mysql query SELECT id name FROM user 我收集结果 while row
  • 枚举类型的 JAXB 元素

    所以我知道如何创建枚举类型 但是当我为其设置元素类型时 元素字段将只是字符串类型 而不是枚举类型 如何在我的模式中创建枚举并让 JAXB 将其生成为 java 枚举类型 这就是我创建枚举类型和元素的方式
  • 在 C++ 中,当我将值传递给函数时,它是否总是转换为适当的类型?

    如果我有一个像这样的函数void func size t x 我称该函数为func 5 5 立即转换为size t类型 这通常适用于所有类型吗 我问这个问题是因为我发誓我见过人们编写代码 他们做类似的事情func 5 0 将 5 作为双精度
  • 向量中的可变结构

    我正在尝试创建一个向量来跟踪游戏中的敌人 该向量将保存一堆可变结构 我有一个世界结构 其中有敌人作为其成员 如下所示 pub struct World pub player Creature pub enemies Vec
  • Lua表在内存中是如何处理的?

    lua如何处理表的增长 是否相当于ArrayList在Java中 IE 需要连续的内存空间 并且当它变得大于已经分配的空间时 内部数组被复制到另一个内存空间 有什么聪明的方法来引导吗 我的问题是 表是如何存储在内存中的 我不是问如何在 Lu
  • 如何将 Box 转换为 &T?

    如果我有一个特征对象 我该如何调用一个需要特征对象的函数Box
  • 如何避免在 Rust 中使用标准输入换行

    我有这个代码 fn main let mut stdin io stdin let input mut String new loop input clear print Your age stdin read line input pri
  • C 中的自定义数据类型

    我正在研究密码学 需要使用一些非常大的数字 我还使用新的 Intel 指令进行需要 m128i 数据类型的无进位乘法 这是通过使用以浮点数据作为参数的函数加载它来完成的 我需要存储 2 1223 整数 然后对其求平方并存储该值 我知道我可以
  • C# 中值类型和引用类型有什么区别? [复制]

    这个问题在这里已经有答案了 我知道一些差异 值类型存储在堆栈上 而引用类型存储在托管堆上 值类型变量直接包含它们的值 而引用变量仅包含对托管堆上创建的对象位置的引用 我错过了任何其他区别吗 如果是的话 它们是什么 请阅读 堆栈是一个实现细节
  • 从模板切换传递的类型

    在 C 中是否可以检查传递给模板函数的类型 例如 template
  • 一般处理枚举的 Scala 类

    我想创建一个通用类来保存枚举的值 并且还允许访问枚举的可能值 以属性编辑器为例 您需要知道属性的当前值 并且还需要能够知道该属性的其他合法值 并且枚举的类型不应该提前知道 您应该能够使用任何类型的枚举 我的第一个想法是这样的 class E
  • 在向量::resize()和向量::reserve()之间选择

    我正在为我的 a 预先分配一些内存vector数据成员 例子 class A vector
  • 如何解决内存分段并强制FastMM释放内存给OS?

    注意 32 位应用程序不计划迁移到 64 位 我正在使用一个非常消耗内存的应用程序 并且几乎优化了与内存分配 取消分配相关的所有相关路径 应用程序本身没有内存泄漏 没有句柄泄漏 没有任何其他类型的泄漏 据我所知并经过测试 我无法触及的第 3
  • 如何重载“新”方法?

    我刚刚开始学习 Rust 我想知道是否有方法重载方法 首先 我创建了一个结构并使用 impl 来实现基本的 新 方法 然后我想添加带有一些参数的 新 方法 并且我尝试使用 Trait 来实现这一点 以下代码已成功编译 但是当我尝试将 new
  • malloc 实现?

    我正在尝试实施malloc and free对于C 我不知道如何重用内存 我目前有一个struct看起来像这样 typedef struct mem dictionary void addr size t size int freed me
  • 如何从 C 中的指针获取数组的大小?

    我分配了一个 数组 mystruct尺寸的n像这样 if NULL p calloc sizeof struct mystruct n 1 handle error 后来我只能访问p 并且不再有n 有没有一种方法可以确定仅给出指针的数组的长
  • serde_json::from_str 错误,其中字符串来自文件

    extern crate serde json use serde json Value use std fs File use std io prelude fn main let filepath map test anhui txt
  • 我可以获取字节数组并将其反序列化为结构吗?

    我正在从套接字读取一系列字节 并且需要将 n 个字节的每个段作为一个项目放入结构中 use std mem derive Debug struct Things x u8 y u16 fn main let array 22 as u8 7
  • 较低级别的缓存是否可以具有更高的关联性并且仍然保留包含性?

    较低级别的缓存是否可以具有更高的关联性并且仍然保留包含性 假设我们有 2 级缓存 L1 最接近 CPU L2 最接近主内存 L1 高速缓存是与 4 个组关联的 2 路组 假设 L2 高速缓存与 16 个高速缓存行直接映射 并假设两个高速缓存
  • 为什么这不是悬空引用?

    我正在关注第二版TRPL 书 https doc rust lang org book second edition 第二版 并且对其中一项任务有点困惑 在 的最后第10 2节 https doc rust lang org book se

随机推荐