• rust 中 str 与 String; &str &String


    String

    String 类型的数据和基本类型不同,基本类型的长度是固定的,所以可以在栈上分配,而String类型是变长的,所以需要在堆上分配,所以String 类型实际上是一个指向堆的指针。他的结构和Vec很类似。从他的声明看也是一个u8的Vec

    pub struct String {
    vec: Vec<u8>,
    }

    看这样一个定义: Programming Rust 2nd Edition 第三章
    image.png
    image.png
    通过字面量声明的是一个 &str。通过to_string 方法转成一个String类型。
    如果是一个字面量,那实际上是程序中预先分配好的只读内存,如上面的poodles。
    String类型是一个 **拥有堆上数据所有权 **的指针,包含了capacity 和 长度
    &str 是堆上数据的一个 切片,并不拥有数据。当执行to_string 的时候,会将数据拷贝到堆上
    image.png

    str和&str

    下面定义四种不同的类型
    image.png

    image.png
    这里会有一个编译报错,提示 str 类型在编译期无法知道其大小。
    上面说过 str 实际上是 堆上数据的一个切片,所以其类型 应该是 [u8]如下面的一个 Vec 的一个切片的类型就是 [i32]
    而由于slice可以是任意长度,所以slice类型不可以直接存储在变量中(不确定长度的数据没法保存在栈上)。所以slice的数据都是以reference&的形式在使用。
    以vec为例
    image.png
    image.png
    指向一个slice的ref是2字节长度,第一个字节保存了slice第一个元素的指针,第二个字节保存了slice的长度。
    所以str类型是String的切片类型一般无法直接交互,&str是切片类型的引用。
    另外对于 str 类型,虽然不能直接交互,但是可以在上面定义方法,比如上面提到的to_string方法
    image.png

    &String

    通常来说 String 在栈上分配,数据存储在堆上,而&String是指向 String 的引用。&String 有点类似于&str 不过 &str直接指向了 切片的第一个元素,而&String首先指向了String,再指向heap,感觉开销会更大一些? 不过可能编译期会处理掉这个开销。总之看起来 &String没有什么使用需求。

    再对比下Java 中的String,实际Java的String对象和基本对象不同,也是一个引用所以可以存储在栈上,而String内部存储数据的是一个byte[]数组。Java String对象本身也是不可变的,修改字符串会重写在堆上分配内存重写新的。
    Java中除了基本类型,其他类型都是引用类型,屏蔽了内部这些细节,而rust中对这些做了区分,交给用户来进行处理。

    除了String之外,rust中的字符串相关的类型还有
    image.png

    参考

    https://www.reddit.com/r/rust/comments/fgpdb0/trying_to_understand_str_vs_str_t_vs_t_osstr_vs/

  • 相关阅读:
    气象台卫星监测vr交互教学增强学生的学习兴趣和动力
    常用半导体器件
    Linux 字符界面切换图形界面
    WPF中动画
    Access-Control-Allow-Origin跨域问题,使用Nginx配置来解决
    防暴力破解服务器ssh登入次数限制
    c++面试题总结
    Vue2.0项目自适应于不同分辨率
    为 VitePress 网站添加 RSS 订阅支持
    [算法笔记]最长公共连续子串
  • 原文地址:https://www.cnblogs.com/Aitozi/p/17406915.html