rust
是门强类型的编程语言,不像js那样同一个变量可以随时变换不同的数据类型。对于习惯了这类编程的语言开始会有点不习惯,见多了就会习惯了。因为是强类,不同的类型之间不能运算不能比较,泾渭分明得很。rust
因为所有权的问题,在数据类型我习惯分为两种:基础数据类型(栈)及复合数据类型(堆)。数据存储在栈或堆上是有很大的区别,一个比较重要的区别是:我目前所知道是栈上的数据是隐性的实现了 Copy Trait
,而堆则没有,Copy Trait
可以规避一些所有权问题,一个相当不错的特性。
基础数据类型(栈)
- 数字类型:u8/i8,u16/i16,u32/i32,f32/f64,isize/usize
- 字符:char
- 字符串:&str
- 布尔:false/true
- 数组:
[i32; 5]
(如果成员不是基础数据类型,那么会引发所有权问题) - 单元类型:
()
函数默认的返回值就是这个
复合数据类型(堆)
- 字符串:String(这个就有点意外了)
- 动态数组:Vec
- 结构体:struct
- 枚举:enum
此篇以基础数据类型做介绍,主要内容是类型说明,注意事项等等
在基础的类型中,数字类型细化的很多,u
代表是没符号,只有正数,i
代表是有符号有正负,size
是根据系统来决定大小(不会是小数),8/16/32/64
代表位数,
在rust
中变量的定义是以let
开头,可以理解为把值绑定到变量名(为什么不用赋值来表达,当你理解所有权这个思想,我觉得你也会这么认为的)。默认变量不可变,是的变量不可变,如果要变量可变则要用let mut
来定义,至于原因:安全。
数字类型
对我来说rust
中的数字不单只是数字,而是对象,在php
求个绝对值是使用函数,在rust
中可以直接用方法比如对-2
求绝对值,但不仅仅于此,还有更多的功能比如:向上/下取整,
-2i32.abs();
在数字的定义上有好几种方面,可以选择自己喜欢来就可以,以下的定义都是等价的
let a: i32 = 8888;
let b = 8888i32;
let c = 8888_i32;
let d = 8_888i32; // 可读性更好
上面有说到,不同的类型是不能比较,虽说都是数字但同样也不能比较如下所示值都是12
但u8
与i32
类型是不一样的,所以是不能相比较
let a = 12u8;
let b = 12i32;
if a == b {
println!("a==b");
}
运行会有如下错误提示
16 | if a == b {
| ^ expected `u8`, found `i32`
|
help: you can convert `a` from `u8` to `i32`, matching the type of `b`
|
16 | if i32::from(a) == b {
| ++++++++++ +
你说字符与数字不能比较我还能接受,但数字与数字不能比较,我不能接受,解决的方法是有的,那就是类型转换,不过有一点要注意的是,小转换为大没问题,大转小就有可能出现问题
,至于原因也很简单,2L的水倒入1L容量的瓶子,会有大量的溢出。目前我所知道转换的方式有
as
大转小不会报错,try_into
大转小有可能会报错,返回的是一个Result
类型,这种类型都代表的有可能会失败。parse
用于广义上的字符(&str
,String
)转化为数字,返回的类型也是Result
fn main() {
// as
let a = 8u8;
let b = 258i32;
if a == (b as u8) {
println!("相等");
}
let a = 8u8;
let b = 8888i64;
// try_into 会报错,原因是溢出
// let b_ = b.try_into().unwrap();
// if a != b_ {
// println!("不相等");
// }
// parse
// 公式是: &str.parse::<转化后的类型>();
let a = "8".parse::<u8>().unwrap();
let b = "8".parse::<i32>().unwrap();
}
上面有用到==
这个运算符来比较两个变量是否相等,这是常用的比较方式,对于整数来说问题不大,但对于浮点数来说问题就很大了
,有句话是这么说的:避免浮点数的相等性
,下面的代码很经典很有代表性:有种0.3
不是0.3
感觉
fn main() {
let a: f64 = 0.3;
let b: f64 = 0.1 + 0.2;
// [错误]
if a == b {
println!("支付金额相等,支付成功");
}
println!("a={} b={}", a, b); // a=0.3 b=0.30000000000000004
// [正确]极小值对比
if a - b < f64::EPSILON {
println!("支付金额相等,支付成功");
}
}
是不是很惊讶,如果用到类似的处理,你就要可以注意了,对于这类的比较使用的方法是,测试运算结果是否在可接受的范围,这个范围通常被称为极小值(epsilon)
,这也说明运算结果有可能现出异常问题,但不会报错,运算出来的结果有可能是NaN
或inf
之类的,这也是开头说的,数字并不单是数字
布尔(bool),单元类型(())
单元类型感觉用的比较少也比较简单,布尔就不用多说。关于单元类型,有一点要注意,所有函数都有返回值并且这个默认值就是单元类型()
。以下最后返回一个()
但在main
又没有标记,是正确
fn main() {
let a: char = 'I';
let c: char = 'T';
println!("{}", format!("{}{}", a, c));
let y: bool = true;
let n: bool = false;
if y != n {
println!("两人意见不一致");
}
return ();
}
字符,字符串
字符与字符串都是用来表示自然字符的方式,以 char
及&str
的形式出现。字符相对用的少,字符串则很常用。
// 字符
let mut c = 'I';
c = 'L'
c = 'Y'
// 字符串
let s = "string"
小小问题
- 一个数字除于0是否会像其它编程那样抛异常,这类问题该如何处理,欢迎留言探讨
- 字符串不能变大小,这个怎么解决
The End.