[初学rust] 02_rust 中的变量和数据类型

rust 中的变量和数据类型

变量

变量声明

  • 使用let来声明变量
  • 并且必须指定类型
  • 默认定义的变量都是i32类型
  • 使用 mut关键字(mutable缩写),来指定变量为可变的
    let a = 1;
    println!("a is {}", a);
    let b = 2i32;
    let c = 3_i32;
    let mut d = 4;
    println!("b is {}, c is {}, d is {}", b, c, d);

使用下划线开头忽略未使用的变量

命名

rust命名规范

变量绑定

  • 使用=来进行变量的绑定
  • 变量默认是不能重新绑定的
  • 不能在一个表达式中同时进行多次绑定
  • 如果是不可变的,则必须先声明后赋值
let a = 1;
let b = 2;
a = b; // error[E0384]: re-assignment of immutable variable `a`

变量可变性

  • 默认情况下,变量是不可变的
  • 使用mut关键字来指定变量为可变的
    let mut h = 1;
    h = 2;
    println!("h is {}", h);

好处:

  • 可变变量最大的好处就是使用上的灵活性和性能上的提升
  • 不可变可以带来安全性,但是丧失了灵活性和性能

变量解构

这个类似于C++的结构化绑定

    let (x, y) = (1, 2);
    println!("x is {}, y is {}", x, y);

常量

  • 使用const关键字来声明一个常量
  • 必须指定类型
  • 不能使用mut关键字
  • 常量的值必须在编译时就已知
const MAX_POINTS: u32 = 100_000;
println!("MAX_POINTS is {}", MAX_POINTS);

变量遮蔽(shadowing)

和C++不同的是,同作用域下rust也会有变量遮蔽

let x = 5;
let x = x+1;

这种算是变量不太灵活的补丁

基本类型

  • 数值类型: 有符号整数 (i8, i16, i32, i64, isize)、 无符号整数 (u8, u16, u32, u64, usize) 、浮点数 (f32, f64)、以及有理数、复数
  • 字符串:字符串字面量和字符串切片 &str
  • 布尔类型: true和false
  • 字符类型: 表示单个 Unicode 字符,存储为 4 个字节
  • 单元类型: 即 () ,其唯一的值也是 ()

类型推导与标注

推导和C++大致一致
标注则是在变量处添加变量类型

let gus:i32 = 1; // i32 就是标注

整数类型

长度有符号类型无符号类型
8 位i8u8
16 位i16u16
32 位i32u32
64 位i64u64
128 位i128u128
视架构而定isizeusize

类型定义的形式统一为:有无符号 + 类型大小(位数)。

  • 无符号数表示数字只能取正数和0
  • 有符号则表示数字可以取正数、负数还有0。

isize 和 usize 类型取决于程序运行的计算机 CPU 类型
字面量书写:

数字字面量示例
十进制98_222
十六进制0xff
八进制0o77
二进制0b1111_0000
字节 (仅限于 u8)b’A’

上面rust除了和python使用了 _这种更容易读的助记符之外,其他的前缀和C一样

溢出

和C一样,Rust也有整数溢出的问题。
只是在debug模式下,会检测这个溢出,release不检测

如何处理:使用标准库提供的方法

    let a: u8 = 255;
    let b = a.wrapping_add(20);
    println!("a is {}, b is {}", a, b);

浮点数类型

  • f32和f64分别表示单精度和双精度浮点数。
  • 默认浮点为 f64
  • 默认情况下,Rust 使用 IEEE-754 标准来表示浮点数。

浮点数的问题,C到rust是一致的:

  • 浮点数不能精确表示无限多的小数
  • 浮点数只是数字的近似值
  • 浮点数无法计算相等

使用准则:

  • 避免在浮点数上测试相等性
  • 不要使用浮点数来表示货币金额

NaN

  • 表示未定义的结果
  • 所有跟 NaN交互的操作,都会返回一个NaN
  • 使用is_nan()方法来判断一个浮点数是否为NaN
    这里和js类似
let a = f64::NAN;
println!("a is {}", a);
assert!(a.is_nan()); 

运算

加减乘除取模

  • 类型之间不能做运算

位运算

  • 使用&进行按位与操作
  • 使用|进行按位或操作
  • 使用^进行按位异或操作
  • 使用!进行按位非
  • 使用<<进行左移操作(右位补0)
  • 使用>>进行右移操作(正数补0,负数补1)
    这里和C++一致,但是rust对于整数的位运算也有了限制
    let a:i8 = 0b0011_1111;
    let b:i8 = 0b0001_1111;
    println!("(a & b) value is {}", (a & b));
    println!("(a | b) value is {}", (a | b));
    println!("(a ^ b) value is {}", (a ^ b));
    println!("(a << 2) value is {}", (a << 2));
    println!("(a >> 2) value is {}", (a >> 2));
    println!("(!b) value is {}", (!b));

序列

Rust提供简单的方式生成序列
序列只允许用于数字或字符类型

for i in 1..5 { //左闭右开[1, 5)
    println!("{}", i);
}
for i in 1..=5 { //左闭右闭[1, 5]
    println!("{}", i);
}

使用 As 进行 类型转换

  • 使用as关键字来强制转换
  • 如果不能转换,则会报错
    TODO

有理数和复数

这个rust标准库还没有,需要自己引包

字符类型 char

  • 字符类型占一个 Unicode Scalar Value(标量值),就是4个字节
  • 使用单引号括起来的 是字符
let x = '中';
println!("字符'中'占用了{}字节的内存大小",std::mem::size_of_val(&x));

布尔

true 和 false,布尔值占用内存的大小为 1 个字节

let b = true;
let f: bool = false;
if !f {
    println!("f {}",std::mem::size_of_val(&f));
}

单元类型

唯一的值是 ()
表达式返回值如果没有,rust隐式返回()

语句和表达式

rust 中 语句 和表达式是有明显含义的,应该是在解析阶段,语句作为顶层解析
表达式作为语句中的元素被解析

  • 语句默认后面加个分号
  • 表达式有返回值
  • 表达式表现和C++大致一致,调用函数,加减乘除之类的都叫表达式

总结

  • 变量的类型是在编译期确定的,不能改变。
  • 类型之间不能进行运算,除非使用as关键字来强制转换。
  • 数据类型种类和C++差不多
  • Rust的数据类型是有method的,可以直接调用
  • 9
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值