u32转换bool类型_Rust数据类型

本文介绍了Rust编程语言中的数据类型,包括变量声明、基本数据类型(如bool、char、整数、浮点数)、指针类型、复合数据类型(如元组、结构体、枚举)以及类型转换。特别强调了Rust中的类型系统和变量绑定,以及在不同模式下整数溢出的处理方式。此外,还讨论了变量遮蔽、类型推导、类型别名和静态变量的概念。
摘要由CSDN通过智能技术生成

变量

Rust是静态强类型语言,所有的变量都有严格的编译期语法检查。

变量声明

格式:

let variable : i32 = 100;

rust要声明的变量前置,而对类型后置。应为最重要的是变量本身,而类型是个附属的额外描述,并非不可或缺,如果编译器可以通过上下文环境自动分析出这个变量的类型,那么就可以不写,并且每个变量都必须合理初始化之后才能被使用。

声明的变量默认是只读的,如果直接编译,会报错re-assignment of immutable variable

let mut x=5; //设定变量可写

也可声明多个变量:

let (mut a, mut b)=(1,2);

let Point {x:ref a,y:ref b}=p

在Rust中,一般把生命局部变量并初始化的语句称为“变量绑定”,与“赋值初始化”有所区别。

变量类型

一般数据类型bool let x = true;

char

设计目的是为了描述任意一个unicode字符,占4个字节。 let love = '❤';

整数类型

字面量后面可以跟后缀,代表数字的具体类型

let var1 = 123usize; // 1变量是usize类型

let var2 = 0x_ff_u8; // 2变量是u8类型

let var3 = 32; // 不写类型,默认为 i32 类型

对于溢出的处理:

在debug模式下,会自动插入整数溢出检查,一旦发生溢出,引发panic。

在release模式下不检查整数溢出,采用自动舍弃高位的方式。浮点数

两种类型,f32和f64

在标准库中,有一个std::num::FpCategory枚举,表示了浮点数可能的状态:

enum FpCategory {

Nan, //不是数字,举例:0.0f32 / 0.0

Infinite, //无穷大,举例:1.0f32 / 0.0

Zero, //0

Subnormal, //当浮点数小到无法在指定范围内合理表达的程度,进入此状态。精度会低些

Normal, //表示正常浮点数

}指针类型

rust没有GC(内存回收机制),对数据的组织操作有更多的自由度。

智能指针

类型转换

rust的类型转换为了防止隐藏的bug,使用as关键字将转换显式地标记出来,且只允许编译器认为合理的类型转换。 fn main() {

let i = 42;

// 先转为 *const i32,再转为 *mut i32

let p = &i as *const i32 as *mut i32;

println!("{:p}", p);

}

复合数据类型

在其他类型的基础上形成的更复杂的组合关系,数组和字符串放到之后讲。tuple

元组类型。 let a = (0,); // a是一个元组,它有一个元素

let a = ("b", (1i32, 2i32));

有两种方式可以访问元组内部元素,模式匹配(Rust的特色之一,后文讲)和数字索引。 let p = (1i32, 2i32);

let (a, b) = p;

let x = p.0;

let y = p.1;

println!("{} {} {} {}", a, b, x, y);

元组内部也可以一个元素都没有,叫unit(单位类型),占用0内存空间。 let empty : () = ();

struct

结构体类型 struct Point{

x: i32,

y: i32,

}

初始化 fn main(){

let p = Point{x:0,y:0};

println!("Point is at {} {}",p.x,p.y);

}

如果变量名恰巧一致,可以使用简略写法 fn main() {

// 刚好局部变量名字和结构体成员名字一致

let x = 10;

let y = 20;

// 下面是简略写法,等同于 Point { x: x, y: y },同名字的相对应

let p = Point { x, y };

println!("Point is at {} {}", p.x, p.y);

}

如果类型相同,也可以进行绑定。 fn main() {

let p = Point { x: 0, y: 0};

// 声明了px 和 py,分别绑定到成员 x 和成员 y

let Point { x : px, y : py } = p;

println!("Point is at {} {}", px, py);

// 同理,在模式匹配的时候,如果新的变量名刚好和成员名字相同,可以使用简写方式

let Point { x, y } = p;

println!("Point is at {} {}", x, y);

}

语法糖,用一种简化的语法复制使用另外一个struct的部分成员。 struct Point3d{

x:i32,

y:i32,

z:i32,

}

fn default() -> Point3d{

Point3d{x:0,y:0,z:0}

}

tuple struct

它就像是tuple和struct的混合。区别在于tuple struct有名字,而它们的成员没有名字。 struct point(

o:i32,

1:i32,

2:i32,

)

tuple、struct和tuple struct区别

struct T1 {

v: i32

}

// define tuple struct

struct T2(i32);

fn main() {

let v1 = T1 { v: 1 };

let v2 = T2(1); // init tuple struct

let v3 = T2 { 0: 1 }; // init tuple struct

let i1 = v1.v;

let i2 = v2.0;

let i3 = v3.0;

}

当tuple struct中只包含一个元素的时候就是newtype idiom,可以非常方便地在一个类型的基础上创建一个新的类型。 fn main() {

struct Inches(i32);

fn f1(value : Inches) {}

fn f2(value : i32) {}

let v : i32 = 0;

f1(v); // 编译不通过,'mismatched types'

f2(v);

}

经修改: fn type_alias() {

type I = i32;

fn f1(v : I) {}

fn f2(v : i32) {}

let v : i32 = 0;

f1(v);

f2(v);

}

enum

如果说tuple、struct、tuple struct在Rust中代表的是多个类型的”与“关系,那么enum(枚举)代表的就是“或“关系。 enum Number{

Int(i32),

Float(f32),

}

在Rust中,emun和struct为内部成员创建了新的namespace,可通过::访问内部成员,不同struct或enum中的重名元素也不会互相冲突。 enum Message{

Quit,

ChangeColor(i32,i32,i32),

Move{x:i32,y:i32},

Write(String),

}

let x:Message = Message::Move{x:3,y:4};

enum Point{

Move{a:i32,b:i32},

}

let y:Point = Point:Move{a:3,b:4};

变量遮蔽

Rust允许在同一个代码块中声明同样名字的变量。但这样会使前面声明的变量被遮蔽。

fn main() {

let x = "hello";

println!("x is {}", x);

let x = 5;

println!("x is {}", x);

}

被遮蔽之后就无法访问前面一个变量。这种方式是十分有效,例如类型转换,修改可变性。

fn main() {

let mut v = Vec::new(); // v 必须是mut修饰,因为我们需要对它写入数据

v.push(1);

v.push(2);

v.push(3);

let v = v; // 从这里往下,v成了只读变量,可读写变量v已经被遮蔽,无法再访问

for i in &v {

println!("{}", i);

}

}

反之亦然

fn main() {

let v = Vec::new();

let mut v = v;

v.push(1);

println!("{:?}", v);

}

变量推导

将数据类型交由编译器自动推导

fn main() {

let player_scores = [

("Jack", 20), ("Jane", 23), ("Jill", 18), ("John", 19),

];

// players 是动态数组,内部成员的类型没有指定,交给编译器自动推导

let players : Vec<_> = player_scores

.iter()

.map(|&(player, _score)| {

player

})

.collect();

println!("{:?}", players);

}

类型别名

type Age = u32

fn grow(age: Age, year: u32) -> Age {

age + year

}

fn main() {

let x : Age = 20;

println!("20 years later: {}", grow(x, 20));

}

静态变量

如果想使用复杂的静态变量初始化,可以使用lazy_static库

fn main() {

//局部变量声明,可以留待后面初始化,只要保证使用前已经初始化即可

let x;

let y = 1_i32;

x = 2_i32;

println!("{} {}", x, y);

//全局变量必须声明的时候初始化,因为全局变量可以写到函数外面,被任意一个函数使用

static G1 : i32 = 3;

println!("{}", G1);

//可变全局变量无论读写都必须用 unsafe修饰

static mut G2 : i32 = 4;

unsafe {

G2 = 5;

println!("{}", G2);

}

//全局变量的内存不是分配在当前函数栈上,函数退出的时候,并不会销毁全局变量占用的内存空间,程序退出才会回收

}

常量

const GLOBAL: i32 = 0

常量不允许使用mut关键字修饰。与静态变量的最大区别在于编译器并不一定会给const常量分配内存空间,在编译过程中,它很可能会被内联优化,因此,用户千万不要用hack的方式,通过unsafe代码去修改常量的值,这么做是没有意义的。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值