首页 > 其他分享 >rust 中 str 与 String; &str &String

rust 中 str 与 String; &str &String

时间:2023-05-16 21:44:10浏览次数:42  
标签:slice String 切片 str 类型 rust

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> 的一个切片的类型就是 [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/

标签:slice,String,切片,str,类型,rust
From: https://www.cnblogs.com/Aitozi/p/17406915.html

相关文章

  • 最新Cobalt strike 4.8(专业版)([*] Generating X509 certificate and keystore (for SSL
    ColbaltStrike搭建和使用 下载: https://anonfiles.com/eay1D0rfzc/CobaltStrike4_8_lusuo_rar解压(如有)密码:lusuokali中: ┌──(root㉿kali)-[~]└─#unrarxCobaltStrike4_8_lusuo.rar    以kali为服务端打开 报错是因为没给可执行权限......
  • Linux基础21 进程介绍, 进程监控状态ps, 进程相关命令pstree,pgrep,pidof, 动态进程监
    1.进程的管理:当我们运行一个程序,那么我们将该程序叫进程 进程线程协程 linux起服务会有给这个服务预分配的内存结构,windows没有 2.为什么要学进程管理?为了管理架构的服务 3.程序和进程的区别1)程序:开发写出来的代码,程序是永久存在的。 2)进程:它会随着程序的终止而销......
  • Codeforces 1158E - Strange device(交互)
    一个有点烦的\(8\logn\)的做法。大致想法大家都一样:以\(1\)为根,然后先问出每个点深度,再问出每个点的父亲。首先先用一个log的做法问出树高,具体做法是直接令根节点的\(f\)为二分出的\(mid\),看能否覆盖所有点即可,记最大深度为\(mxdep\)。可以在二分过程中顺带着求出深......
  • 用Rust实现DES加密/解密算法
    信息安全技术课程要求实现一下DES算法。对着一份Java代码断断续续抠了几天,算是实现出来了。这里记录一下算法思想和我的Rust实现。DES算法解析概述https://en.wikipedia.org/wiki/Data_Encryption_StandardDES是一种对称的分组加密算法,加密和解密使用同一个密钥,计算过程将数......
  • Rust 笔记 - 2
    结构体初始化Rust的结构体类似于C,使用关键字struct声明。structUser{active:bool,sign_in_count:u32,username:String,email:String}结构体中的每个元素称为“域”(field),域是可修改的(mutable),使用.来访问域的值。创建实例为了使用结构体,需要根据结......
  • Date和String的转换
    1importjava.text.DateFormat;2importjava.text.SimpleDateFormat;3importjava.text.ParseException;4importjava.util.Calendar;5importjava.util.Date;678DateFormatformat=newSimpleDateFormat("yyyy-MM-dd&qu......
  • hibernate Restrictions用法
    [url]http://xuganggogo.iteye.com/blog/440078[/url]QBC常用限定方法[b]Restrictions.eq-->equal,等于.Restrictions.ne-->不等于Restrictions.allEq-->利用Map来进行多个等于的限制,参数为Map对象,使用key/value进行多个等于的比对,相当于多个Re......
  • 1091 Acute Stroke
       易错点:1、注意结果大于等于t才能计入2、bfs中此处记住是top.x不是xinttl=top.x+L[w];inttm=top.y+M[w];inttn=top.z+N[w];3、数组大小开错了(注意数组每一维度是什么及其对应的大小) ......
  • Java通过反射获取Fields、Method、Constructor示例
    1.getFields()和getDeclaredFields()getFields能获取该类和父类(包括Object)public的属性,getDeclaredFields获取该类public和private的属性2.getMethods()和getDeclaredMethods()getMethods能获取该类和父类(包括Object)public的方法,getDeclaredMethods获取该类public和privat......
  • 由于string不能输入空格,和cin不能输入空格;用了map和vector和cin.get()的题;本题都正确
    1.cin是C++中最常用的输入语句,当遇到空格或者回车键即停止。无法解决。2.cin.get()函数可以接收空格,遇回车结束输入。3.string也不能输入空格给定两个字符串 A 和 B,本题要求你输出 A+B,即两个字符串的并集。要求先输出 A,再输出 B,但重复的字符必须被剔除。输入格式:输......