rust数据类型

news2025/9/6 23:45:49

一,基本类型

1,基本类型

(1)整数类型

	let x=111_222_3334;
	let y:u16=1123;

整数默认是i32类型,整数中间的下划线可以忽略。

(2)浮点数

在 Rust 中浮点类型数字也有两种基本类型: f32 和 f64

	let x=2.5;
	let y:f32=1.23;

浮点数默认是f64类型。

浮点数都有唯一的非自反元素NAN,所以std里面判断一个数是不是NAN的源码是这么写的:

    pub const fn is_nan(self) -> bool {
        self != self
    }

(3)bool类型

取值:false true

(4)char类型

    let heart_eyed_cat:char = '😻';
    println!("{}",heart_eyed_cat);
    let z:char = '我';
    println!("{}",z);

rust的char类型范围比较大,中文甚至emoji都算,char类型大小为4个字节。

char类型大小为什么是为4个字节?

因为rust字符串采用utf-8编码,而utf-8一个字符最多占4个字节。

char和整数互转规则:

u8可以用as转为char,u16和u32都不行,而char可以用as转为u8和u16和u32

    let x:u8=100;
    let c=char::from(x);
    let x:u32=100;
    let c2=char::from_u32(x);
    assert_eq!(c2,Some(c));
    let c3=char::try_from(x);
    assert_eq!(c3,Ok(c));

2,基本类型的代数结构

在c++中,基本类型都是有等价关系的。

然而在rust中,浮点数只有部分等价关系,没有等价关系,Rust 的整数类型、字符串类型、布尔类型都有等价关系。

所以,哈希表的key类型可以是整数类型、字符串类型、布尔类型,不能是浮点数类型。

二,复合类型

1,序列、单元序列、切片

序列,也称为数组

(1)自动生成序列:

序列相当于是整数的复合类型。

	for i in 1..=5{	
	    println!("{}",i);
	}

带了等号,所以序列是1,2,3,4,5

去掉等号,序列就是1,2,3,4

(2)普通序列、切片

fn main() {
    let mut c = [1,2,3,4,8,6];
    let slice = &mut c[1..3];
    slice[0]=9;
    assert_eq!(c,[1,9,3,4,8,6]);
}

c就是普通序列(数组),slice就是切片

(3)单元序列

单元序列就是空序列:

    let mut x =Vec::from([]);
    x.push(5);

2,元组、单元元组

(1)元组

    let t = (1,1.5,"what");
    assert_eq!(t.0, 1);
    assert_eq!(t.1, 1.5);
    assert_eq!(t.2, "what");

(2)单元元组

单元元组就是空元组,有2种用法,一是用于没有返回值的函数:

fn f() {
    print!("{}",123);
}
fn f2()->() {
    print!("{}",123);
}
fn f3()->(){
    print!("{}",123);
    return ();
}

 二是用作map的值,表示不关心值,只关心key。

fn main() {
    let mut map = HashMap::new();
    assert_eq!(map.insert(3, ()), None);
    assert_eq!(map.insert(5, ()), None);
}

3,结构体、空结构体、单元结构体

(1)结构体

#[derive(PartialEq, Eq, Clone, Debug)]
struct S{
    x:i32,y:i32
}
fn main() {
    let s1=S{y:1, x:2};
    let s2=S{x:3,..s1};
    assert_eq!(s2,S{x:3,y:1});
    println!("end");
}

创建结构体实例时,必须写明成员名:成员值,所以顺序也叫无所谓了。

(2)2种省略写法

省略写法一:可以根据一个结构体实例创建另一个结构体实例,除了写明的成员,其他成员用相同值进行初始化。

struct Pointer{
    x:i32,
    y:i32
}
fn main() {
    let a=Pointer{x:3,y:4};
    let p=Pointer{x:5,..a};
    assert_eq!(5,p.x);
    assert_eq!(4,p.y);
}

其中..a表示从a抄录部分成员值,..a必须写在最后面

省略写法二:可以把形如x:x简写成x,必须完全同名时才可以简写。

struct Pointer{
    x:i32,
    y:i32
}
fn main() {
    let x=5;
    let a=Pointer{x:x,y:4};
    let p=Pointer{x,y:4};
    assert_eq!(5,p.x);
    assert_eq!(4,p.y);
    let p=Pointer{y:4,x};
    assert_eq!(5,p.x);
    assert_eq!(4,p.y);
}

小结:

..a必须写在最后面,其他的成员赋值无论先后,每一个都可以按照名字严格对应。

(3)空结构体

struct S{}

fn main(){
    let a=S{};
    //let b=S; //error
}

(4)单元结构体

单元结构体的定义最简洁,只有一个名字:

struct S2;

fn main(){
    let c=S2{};
    let d=S2;
}

4,元组结构体、单元元组结构体

(1)元组结构体

元组结构体就是又像元组又像结构体的一种数据结构,语法和元组和结构体都不一样。

struct Point(i32, i32, i32);

fn main() {
    let x = Point(3,0,0);
    assert_eq!(x.0, 3);
}

PS:结构体成员是必须按照名字对应,顺序无所谓,元组结构体是必须按照顺序对应,没有名字。

(2)单元元组结构体

struct S();

fn main() {
    let x=S();
    print!("end");
}

5,枚举

枚举的BNF:

Enumeration :
   enum IDENTIFIER  GenericParams? WhereClause? { EnumItems}

EnumItems :
   EnumItem ( , EnumItem )* ,?

EnumItem :
   OuterAttribute* Visibility?
   IDENTIFIER ( EnumItemTuple | EnumItemStruct )? EnumItemDiscriminant?

EnumItemTuple :
   ( TupleFields? )

EnumItemStruct :
   { StructFields? }

EnumItemDiscriminant :
   = Expression

也就是说,枚举的成员可以有3种类型随意组合,分别是元组tuple,结构体,还有表达式

虽然说单个整型变量也是表达式,但是枚举里面的表达式好像只能是整型变量。

(1)枚举的成员

细分下来一共是五种:

enum Enum0 {
    Tuple1(),
    Tuple2(i32,f32),
    Struct1{},
    Struct2{x:i32,y:f64},
    X,
}

五个成员分别是单元元组,元组结构体,单元结构体,结构体,整型变量。

所有的枚举成员,都对应一个整型值,默认是isize类型,允许编译器采用更小的整数类型。

(2)整型值的显式声明

前提条件:要么只有整型变量,要么用repr显式声明了枚举整数类型

enum Enum1 {
    X=7,
    Y,
    Z=-100
}

#[repr(u8)]
enum Enum2 {
    Tuple1(),
    Tuple2(i32,f32),
    Struct1{},
    Struct2{x:i32,y:f64},
    X=200,
}

(3)整型值的隐式推导

推导规则:从有显式声明的,往下依次加一,如果第一个成员没有声明,那就是0

推导失败就编译失败:按照推导规则发现有重复值的(包括显式声明重复值的),或者推导值超出了整数范围的,就编译失败

(4)直接使用枚举值

最简单的例子:

#[derive(Debug,PartialEq)]
enum Enum {
    X=200,
}

fn main() {
    let x=Enum::X;
    assert_eq!(Enum::X, x);
}

Debug和PartialEq都是必须声明的。

复杂一点的例子:

#[repr(u8)]
#[derive(Debug,PartialEq)]
enum Enum {
    Tuple1()=3,
    Tuple2(i32,i64),
    Struct0{},
    Struct1{},
    Struct2{x:i32,y:i64}=100,    
    X=200,
}

fn main() {
    let x1 = Enum::Tuple1();
    let x2 = Enum::Tuple2(5,6);
    let x3=Enum::Struct0{};
    let x4=Enum::Struct1{};
    let x5=Enum::Struct2{x:7,y:8};
    let x6=Enum::X;
    assert_eq!(Enum::Tuple1(), x1);
    assert_eq!(Enum::Tuple2(5,6), x2);
    assert_ne!(x1,x2);
    assert_eq!(Enum::Struct0{}, x3);
    assert_ne!(x3,x4);
    assert_eq!(Enum::Struct2{x:7,y:8}, x5);
    assert_ne!(Enum::Struct2{x:9,y:9}, x5);
    assert_eq!(Enum::X, x6);
}

Enum里面2个单元结构体是不相等的。

对于2个枚举变量对应的是Enum里面同一个枚举值的,比如都是Struct2,还需要里面的成员相等,2个枚举变量才完全相等。

(5)把枚举值转换成整数

前提条件:只由单元元组、单元结构体、整型变量构成,且只有整型变量有显示声明整型值

#[repr(u8)]
enum Enum {
    Tuple1(),
    X=100,
    Tuple2(),
    Struct0{},
    Y=200,
    Struct1{},    
}

fn main() {
    assert_eq!(Enum::Tuple1() as u8, 0);
    assert_eq!(Enum::X as u8, 100);
    assert_eq!(Enum::Tuple2() as u8, 101);
    assert_eq!(Enum::Struct0{} as u8, 102);
    assert_eq!(Enum::Y as u8, 200);
    assert_eq!(Enum::Struct1{} as u8, 201);
}

6,数据大小

use std::mem::size_of;

use std::mem::size_of_val;

(1)基本类型

fn main() {
    assert_eq!(size_of::<i8>(),1);
    assert_eq!(size_of::<u8>(),1);
    assert_eq!(size_of::<i16>(),2);
    assert_eq!(size_of::<u16>(),2);
    assert_eq!(size_of::<i32>(),4);
    assert_eq!(size_of::<u32>(),4);
    assert_eq!(size_of::<i64>(),8);
    assert_eq!(size_of::<u64>(),8);
    assert_eq!(size_of::<i128>(),16);
    assert_eq!(size_of::<u128>(),16);
    assert_eq!(size_of::<f32>(),4);
    assert_eq!(size_of::<f64>(),8);
    assert_eq!(size_of::<bool>(),1);
    assert_eq!(size_of::<char>(),4);
    println!("end");
}

(2)序列、单元序列、切片、空切片、元组、单元元组、枚举

enum Enum {
    X=253,
    Y,
    Z
}
enum Enum2 {
    X=254,
    Y,
    Z
}

fn main() {
    let x=[false,true];//序列=单个尺寸*个数
    assert_eq!(size_of_val(&x),2);
    let x:[bool;0]=[];
    assert_eq!(size_of_val(&x),0);//单元序列=固定0
    let y=&x[..];
    assert_eq!(size_of_val(&y),16);//切片=固定16
    let y=&x[0..0];
    assert_eq!(size_of_val(&y),16);//空切片也是16
    let z=(false,1);
    assert_eq!(size_of_val(&z),8);//元组 4+4
    let z=(1,false,y);
    assert_eq!(size_of_val(&z),24);//元组 4+4+16
    let z=();
    assert_eq!(size_of_val(&z),0);//单元元组=固定0
    assert_eq!(size_of::<Enum>(),1);//枚举的大小等于最大枚举值的大小
    assert_eq!(size_of::<Enum2>(),2);
    println!("end");
}

其中,元组的规则应该是等同于普通结构体。

(3)结构体、空结构体、单元结构体、元组结构体、单元元组结构体

结构体的大小计算涉及到对齐值的概念,这一部分和C相同,具体细节参考结构体大小和对齐值。

不同的是,rust中的结构体默认会自动重排,如果加了#[repr(C)]属性宏则不会重排


struct S1{
    a:u32,
    b:u16,
    c:u8,
}
struct S2{
    b:u16,
    a:u32,
    c:u8,
}
#[repr(C)]
struct S3{
    b:u16,
    a:u32,
    c:u8,
}

struct S4{}
struct S5;
struct S6(i32,bool);
struct S7();

fn main() {
    assert_eq!(size_of::<S1>(),8);//普通结构体
    assert_eq!(size_of::<S2>(),8);//重排结构体
    assert_eq!(size_of::<S3>(),12);//禁止重排的普通结构体
    assert_eq!(size_of::<S4>(),0);//空结构体=固定0
    assert_eq!(size_of::<S5>(),0);//单元结构体=固定0
    assert_eq!(size_of::<S6>(),8);//元组结构体 4+4
    assert_eq!(size_of::<S7>(),0);//单元元组结构体=固定0
    println!("end");
}

(4)指针、字符串

​
fn main() {
    let p=&1 as *const i32;
    let psize = size_of_val(&p);// psize=4或者8,看机器
    let a=&1;
    assert_eq!(size_of_val(&a),psize);//普通引用等同于指针
    let b=&[1,2];
    assert_eq!(size_of_val(&b),psize);//引用数组是普通引用,所以等同于指针
    let c=&b[..];
    assert_eq!(size_of_val(&c),psize*2);//引用切片是胖指针,等同于2个指针
    let s:&str="123";
    assert_eq!(size_of_val(&c),psize*2);//&str是引用切片,所以是胖指针
    let s=String::from("12345678");
    assert_eq!(size_of_val(&s),size_of::<Vec<u8>>());//String对象的大小是固定的,和内部数据长度无关
    println!("end");
}

​

在64位机器上,String是24个字节。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1843002.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

停车场防逃费设备有哪些,捷曜超眸相机怎么样,有哪些功能?

在当今快速发展的城市交通环境中&#xff0c;车场管理面临着诸多挑战&#xff0c;其中防逃费现象尤为突出。频繁的逃费行为不仅给车场运营带来了经济损失&#xff0c;也严重影响了停车场的正常秩序。对于车场防逃费方案中&#xff0c;超眸相机&#xff0c;以其尖端的高清成像技…

企业微信集成策略:打破壁垒,驱动企业数字化转型

随着全球化和数字化的快速推进&#xff0c;企业如何在激烈的市场竞争中脱颖而出&#xff0c;成为每个企业家和决策者关注的焦点。腾讯推出的企业微信&#xff0c;作为一款集沟通、协作、管理于一体的企业通讯与办公工具&#xff0c;正逐步成为企业数字化转型的得力助手。NetFar…

类型“Element”上不存在属性“ondragstart”

先上一下代码&#xff1a; //初始化拖动源事件function initDragSourceNode() {const moveDom document.querySelector(.drag); //拖动元素// console.log(moveDom:, moveDom);moveDom!.ondragstart function (e) {// console.log(拖动开始);};moveDom.ondrag function (e)…

CRMEB 多门店安装系统配置清单

系统在安装完成之后&#xff0c;需要对系统进行一系列的配置&#xff0c;才能正常使用全部的功能&#xff0c;以下是官方整理的配置清单

SEO之预估流量及价值(二)

初创企业搭建网站的朋友看1号文章&#xff1b;想学习云计算&#xff0c;怎么入门看2号文章谢谢支持&#xff1a; 1、我给不会敲代码又想搭建网站的人建议 2、新手上云 &#xff08;接上一篇。。。。&#xff09; 2、点击率 搜索结果页面各排名位置点击率也不精确。前面介绍的…

【第13章】进阶调试思路:如何安装复杂节点IP-Adapter?(安装/复杂报错/节点详情页/精读)ComfyUI基础入门教程

🎈背景 IP-Adapter这个名字,大家可能听说过,可以让生成的结果从参考图中学习人物、画风的一致性,在目前是比较实用的一个节点,广泛的用于照片绘制、电商作图等方面。 但同时,这个节点也是比较难安装的一个节点。 所以,这节课,我们就通过一个案例,来学习如何在Comf…

食品快消品进销存+门店批发+零售商城整体代码输出

食品快消品行业在当今信息化和数字化浪潮中&#xff0c;建立批发零售的信息化系统已成为一种迫切的必要性。通过信息化&#xff0c;食品快消品企业能够实现从生产到销售的全面优化&#xff0c;提高供应链效率&#xff0c;降低运营成本&#xff0c;增强市场竞争力。通过有效的信…

网络安全管理组织架构复习

文章目录 安全管理机构岗位设置安全要求要求解读 安全管理机构 安全管理的重要实施条件就是有一个统一指挥、协调有序、组织有力的安全管理机构,这是网络安全管理得以实施、推广的基础。 通过构建从单位最高管理层到执行层及具体业务运营层的组织体系&#xff0c;可以明确各个…

2024年最热门的5款国产AI画图软件推荐

前言 AI绘画软件正在彻底改变艺术创作和视觉设计的面貌&#xff0c;而国产软件的兴起更是为这一变革注入了新的活力。 它们不仅提升了设计的效率&#xff0c;还极大地拓宽了创意的边界。2024年&#xff0c;我们见证了多款国产AI画图软件的火爆&#xff0c;它们以其强大的功能…

AI融资热潮:Genspark、Finaloop等初创吸金不断!中国气象局发布三大AI模型

文章推荐 AI日报&#xff5c;跃问App上架加入AI助理竞争&#xff01;GPTZero获千万美元A轮融资&#xff0c;创始人不到30岁&#xff01; AI日报&#xff5c;Luma推出AI视频模型&#xff0c;又一Sora级选手登场&#xff1f;SD3 Medium发布&#xff0c;图中文效果改善明显 ⭐️…

有关计算素数的算法

归纳编程学习的感悟, 记录奋斗路上的点滴, 希望能帮到一样刻苦的你! 如有不足欢迎指正! 共同学习交流! 🌎欢迎各位→点赞 👍+ 收藏⭐ + 留言​📝黑暗的笼罩更会凸显光明的可贵! 一、引言 什么是素数 素数,也被称为质数,是指在大于1的自然数中,只能被1和它本身…

SolidWorks教育版使用的优势

随着科技的不断进步和工程教育的深入发展&#xff0c;三维计算机辅助设计软件&#xff08;CAD&#xff09;在高等教育领域中的应用越来越广泛。SolidWorks作为一款三维CAD软件&#xff0c;其教育版在工程类院校中备受青睐。本文旨在探讨SolidWorks教育版在教学中的优势&#xf…

Anti-human IL-12/-23 (p40) mAb (MT3279H), azide free

Anti-human IL-12/-23 (p40) mAb (MT3279H), azide free该单克隆抗体用于中和人IL-12/-23的生物活性。 产品详情&#xff1a; 免疫原&#xff1a;人重组IL-23蛋白 Isotype: mouse IgG2b Specificity: 天然和重组人IL-12和 IL-23蛋白的p40 subunit 浓度&#xff1a;1mg/ml …

机房布线新方案:数字化运维如何助力企业高效腾飞

随着信息量的激增&#xff0c;传统的机房布线管理方式已经难以满足现代化企业的需求&#xff0c;存在着“视觉混乱、记录不准”等严重问题&#xff0c;这不仅影响了机房运维的效率&#xff0c;更对企业的数据安全构成了潜在威胁。然而&#xff0c;随着耐威迪数字化运维管理方案…

java连接kerberos用户认证以及java连接ldap读取账户信息

文章目录 一、背景二、代码2.1目录2.2配置文件application.properties2.3pom依赖2.4代码AuthProviderConfig配置类CustomConfigurationByKeytab配置类CustomConfigurationByPassword配置类LdapConfiguration配置类TestControllerLdapUser实体类MyCallbackHandlerLdapUserAttrib…

深入了解 AndroidX ConstraintLayout 中的 Barrier

androidx.constraintlayout.widget.Barrier&#xff08;简称Barrier&#xff09;是 ConstraintLayout 2.0 中引入的一个新特性&#xff0c;它可以极大地简化复杂布局的实现。本文将详细介绍Barrier 的概念、使用方法以及在实际开发中的应用场景。 什么是 Barrier&#xff1f; …

Linux-账号和权限管理

目录 一、管理用户账号 1、用户账号类型 2、UID--身份标识 3、UID的分类 ​4、用户账号文件​ 5、chage-修改账号密码 5.1、chage—使用格式&#xff1a; 5.2、chage—使用参数&#xff1a; ​6、添加用户账号与管理 6.1、useradd—添加用户 6.2、passwd—设置/修改…

五大数据防泄漏系统排名|高效实用的防泄漏软件有哪些

在数字化时代&#xff0c;数据泄露已成为企业面临的重要安全挑战之一。为了有效应对这一挑战&#xff0c;企业需要借助先进的数据泄露防护系统来保护其敏感信息免受非法访问、使用和泄露。以下是五大备受推崇的数据泄露防护系统&#xff0c;它们各具特色&#xff0c;功能强大&a…

深度学习(十四)——优化器

前言 反向传播可以求出神经网路中每个需要调节参数的梯度(grad)&#xff0c;优化器可以根据梯度进行调整&#xff0c;达到降低整体误差的作用。下面我们对优化器进行介绍。 1. 如何使用优化器 官方文档:torch.optim — PyTorch 2.0 documentation &#xff08;1&#xff09;构…

DataOps真能“降本增效”?

在各行各业中&#xff0c;越来越多的公司开始重视收集数据&#xff0c;并寻找创新方法来获得真实可行的商业成果&#xff0c;并且愿意投入大量时间和金钱来实现这一目标。 据IDC称&#xff0c;数据和分析软件及云服务市场规模在 2021 年达到了 900 亿美元&#xff0c;随着企业继…