• rust &String 和 &str 区别


    1 String / &String

    String 类型的变量本质是一个存放在栈上的胖指针(当然调用过程中,不用显示地按指针那样处理),共有三个字段:

    • 1 pointer: 指向实际字符串值的地址,值是存放在堆上可变字节缓冲区;
    • 2 length: 值Vec< u8 >长度 / 元素个数;
    • 3 capacity: 当前缓冲区容量,当值的长度溢出时,寻找新的合适区间,将值重新拷贝分配到新的内存;同时更新三个字段。

    &String 则表示对 String 类型数据的一个引用,也可以理解成是对上面所说的胖纸针的一个引用,示意图如下:

    在这里插入图片描述

    2 str / &str

    str表示不可变且长度未知的u8类型数据序列这样的数据序列是可以存在于内存的多种地方的;由于其长度未知,强安全的RUST在编译时无法通过,所以str类型数据无法独立使用,通常都采取其引用的形式,也就是字符串切片&str,一个存放在栈上的胖指针(指针本身长度是确定的),其包含两个字段:

    • 1 pointer: 指向实际字符串值的地址;
    • 2 length: 数据[u8]长度 / 元素个数。
      示意图如下:
      在这里插入图片描述

    3 &String 和 &str的比较

    3.1 引用/指针

    引用的本质就是指针,使用上略有不同,但这里为了更好地描述,我就把这两者概念模糊地来讲了。

    • 【栈】&String ->【栈】String -> 【堆】value

    • 【栈】&str -> 【?】value (str)
      str可以在
      1)静态存储区(static storage):最常见的字面量 “foo” 类型便是 &'static str;字面量会以硬编码的方式写入程序的二进制文件中,当程序运行时,加载至ROM(Read Only Memory);
      2)堆上缓冲区数据

      // let s: &String = &String::from("rust"); // 隐式推断, 类型会作为&String处理
      let s: &str = &String::from("rust"); // 显示标注,这里&str可以理解成是对String的全长切片
      
      • 1
      • 2

      其中,from()里的字符串字面量"rust"也会以硬编码形式写入二进制文件中,程序运行时,加载至ROM;创建String变量时,会在ROM中找到对应字符串,然后拷贝至堆中,返回地址、长度、容量字段。
      在这里插入图片描述

      3)栈上的数据:分配在栈上的< u8 >数组

      use std::str;
      fn main() {
      	let arr: [u8; 4] = [b'r', b'u', b's', b't']; // b 将char unicode转换为utf-8
          let stack_str: &str = str::from_utf8(&arr).unwrap(); 
      }
      
      • 1
      • 2
      • 3
      • 4
      • 5

    3.2 类型转换

    常见的转化就不赘述了,可以参考这位博主的文章

    《rust中String,&str,Vec 和&[u8]的惯用转换》https://zhuanlan.zhihu.com/p/372082802

    &String&str 其实都可以看成是对< u8 >序列数据的引用,只不过结合上面的分析可以看出:&String最终指向的数据只会存在于堆上,而&str指向的数据则不然。可以完美地用&str替换&String(表全长String的切片),反过来就不行。
    这也是字符串引用类型通常都是使用&str的原因。
    在这里插入图片描述

        let s1:&str = &String::from("rust");
        let s2:&String = &String::from("rust");
        let s1:&str = "rust";
        // let s2:&String = "rust"; //类型匹配错误, mismatched types expected reference `&String` found reference `&'static str`
    
    • 1
    • 2
    • 3
    • 4
  • 相关阅读:
    沙盒软件-软件多开-命令行-运行参数-进程通信-运行和评估
    5. MyBatis 面试题集锦
    大厂C++协作框架(基辅)技术原理
    Spring Data Elasticsearch集成SpringBoot 2.3.12.RELEASE
    【docker:容器提交成镜像】
    hive使用中的参数优化与问题排查
    Python学习笔记
    如何将Docker镜像源更改为阿里云的镜像加速地址
    B082-SpringCloud-Eureka
    理解TCP协议三次握手、四次挥手、流量控制、拥塞控制 、重传机制
  • 原文地址:https://blog.csdn.net/weixin_44539199/article/details/132896574