变量(基础类型)

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; // 可读性更好

上面有说到,不同的类型是不能比较,虽说都是数字但同样也不能比较如下所示值都是12u8i32类型是不一样的,所以是不能相比较

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 用于广义上的字符(&strString)转化为数字,返回的类型也是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),这也说明运算结果有可能现出异常问题,但不会报错,运算出来的结果有可能是NaNinf之类的,这也是开头说的,数字并不单是数字

布尔(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"

小小问题

  1. 一个数字除于0是否会像其它编程那样抛异常,这类问题该如何处理,欢迎留言探讨
  2. 字符串不能变大小,这个怎么解决

The End.

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值