美文网首页
2# 数据类型

2# 数据类型

作者: IamaStupid | 来源:发表于2022-02-22 14:18 被阅读0次

    Rust 是 静态类型(statically typed)语言,也就是说在编译时就必须知道所有变量的类型。
    在 Rust 中,每一个值都属于某一个 数据类型(data type),这告诉 Rust 它被指定为何种数据,以便明确数据处理方式。我们将看到两类数据类型子集:标量(scalar)和复合(compound)。

    标量类型

    标量scalar)类型代表一个单独的值。Rust 有四种基本的标量类型:整型、浮点型、布尔类型和字符类型。

    复合类型

    复合类型Compound types)可以将多个值组合成一个类型。Rust 有两个原生的复合类型:元组(tuple)和数组(array)。

    整型,浮点型

    整型默认是i32类型,浮点型默认是f64类型。
    两个不同的类型的数据不能运算,包括求余,加,减,乘,除。

    Rust 中的整型

    长度 有符号 无符号
    8-bit i8 u8
    16-bit i16 u16
    32-bit i32 u32
    64-bit i64 u64
    128-bit i128 u128
    arch isize usize

    每一个有符号的变体可以储存包含从 -(2n - 1) 到 2n - 1 - 1 在内的数字,这里 n 是变体使用的位数。所以 i8 可以储存从 -(27) 到 27 - 1 在内的数字,也就是从 -128 到 127。无符号的变体可以储存从 0 到 2n - 1 的数字,所以 u8 可以储存从 0 到 28 - 1 的数字,也就是从 0 到 255。

    另外,isize 和 usize 类型依赖运行程序的计算机架构:64 位架构上它们是 64 位的, 32 位架构上它们是 32 位的。

    整型溢出

    比方说有一个 u8 ,它可以存放从零到 255 的值。那么当你将其修改为 256 时会发生什么呢?这被称为 “整型溢出”(“integer overflow” ),这会导致以下两种行为之一的发生。当在 debug 模式编译时,Rust 检查这类问题并使程序 panic,这个术语被 Rust 用来表明程序因错误而退出。第九章 panic! 与不可恢复的错误” 部分会详细介绍 panic。
    在 release 构建中,Rust 不检测溢出,相反会进行一种被称为二进制补码包装(two’s complement wrapping)的操作。简而言之,值 256 变成 0,值 257 变成 1,依此类推。依赖整型溢出被认为是一种错误,即便可能出现这种行为。如果你确实需要这种行为,标准库中有一个类型显式提供此功能,Wrapping。 为了显式地处理溢出的可能性,你可以使用标准库在原生数值类型上提供的以下方法:

    • 所有模式下都可以使用 wrapping_* 方法进行包装,如 wrapping_add
    • 如果 check_* 方法出现溢出,则返回 None
    • overflowing_* 方法返回值和一个布尔值,表示是否出现溢出
    • saturating_* 方法在值的最小值或最大值处进行饱和处理

    浮点型:f32 f64

    在现代 CPU 中,它与 f32 速度几乎一样,不过精度更高。所有的浮点型都是有符号的。
    浮点数采用 IEEE-754 标准表示。f32 是单精度浮点数,f64 是双精度浮点数。

    数据运算

        let a:i8 = 9;
        let b:i64 = 2;
        let x = a*b;
    
        println!("The value of x is: {}", x);
    
    
    error[E0308]: mismatched types   #不匹配的类型
    

    类型不同,所以报错。

        let a:i64 = 90000;
        let b:i64 = 2;
        let x = a*b;
    
        println!("The value of x is: {}", x);
    
    The value of x is: 180000
    

    数据运算的结果x的类型自动变成了运算数据一样的类型。

        let a = 9;
        let b:i64 = 2;
        let x = a*b;
    
        println!("The value of x is: {}", x);
    
    
    The value of x is: 18
    

    a是整型,理论上默认应该是i32类型,但是数据运算表达式的存在,编译时做了自动类型检查,会被设置成和变量b一样的i64整型

    println!("The value of x is: {}", 1u32 - 2);
    
    error: this arithmetic operation will overflow
    

    1 - 2 = -1;但是结果应该是一个无符号的,所以-1这个数据溢出了。

    布尔型

    Rust 中的布尔类型有两个可能的值:true 和 false。Rust 中的布尔类型使用 bool 表示。

    fn main() {
        let t = true;
    
        let f: bool = false; // 显式指定类型注解
    }
    

    字符类型

    Rust的 char 类型是语言中最原生的字母类型。
    我们用单引号声明 char 字面量,而与之相反的是,使用双引号声明字符串字面量。Rust 的 char 类型的大小为四个字节(four bytes),并代表了一个 Unicode 标量值(Unicode Scalar Value),这意味着它可以比 ASCII 表示更多内容。在 Rust 中,拼音字母(Accented letters),中文、日文、韩文等字符,emoji(绘文字)以及零长度的空白字符都是有效的 char 值。
    由于中文文字编码有两种(GBK 和 UTF-8),所以编程中使用中文字符串有可能导致乱码的出现,这是因为源程序与命令行的文字编码不一致,所以在 Rust 中字符串和字符都必须使用 UTF-8 编码,否则编译器会报错。

    let s = 's';
    let str = "abc"
    

    元组

    元组是一个可以包含各种类型值的组合。元组使用括号 () 来构造(construct),而每个元组自身又是一个类型标记为 (T1, T2, ...) 的值,其中 T1、T2 是每个元素的类型。
    元组长度固定:一旦声明,其长度不会增大或缩小。
    获取元组的值,有两种方式:1.使用 tup.下标 2. 解构

       let x = (500, 6.4, 1);
       let a = x.0;
       let (x, y, z) = x;
       let b = x.2
    
       let x: (i32, f64, u8) = (300, 7.4, 8);
       let a = x.0;
    

    数组

    数组中的每个元素的类型必须相同。Rust 中的数组与一些其他语言中的数组不同,Rust中的数组长度是固定的。
    当你想要在栈(stack)而不是在堆(heap)上为数据分配空间,或者是想要确保总是有固定数量的元素时(比如12个月份),数组非常有用。
    但是数组并不如 vector 类型灵活。vector 类型是标准库提供的一个 允许 增长和缩小长度的类似数组的集合类型。
    数组是可以在堆栈上分配的已知固定大小的单个内存块。可以使用索引来访问数组的元素。

    let months = ["January", "February", "March", "April", "May", "June", "July",
                  "August", "September", "October", "November", "December"];
    let m = months[2]
    

    也可以像这样编写数组的类型:在方括号中包含每个元素的类型,后跟分号,再后跟数组元素的数量。

    let a: [i32; 5] = [1, 2, 3, 4, 5];
    
    let a = [3; 5]; // 等价于 let a = [3,3,3,3,3]
    
    let m = a[1]
    

    相关文章

      网友评论

          本文标题:2# 数据类型

          本文链接:https://www.haomeiwen.com/subject/gvkilrtx.html