rust 标准库·基本数据类型

 

rust标准库的阅读笔记

rust标准库的阅读笔记

1. 数组

一个固定大小的数组,表示为[T;N]T表示元素类型,非负常量N表示元素数量

创建固定数组的方法:

  • 重复表达式[x;N],它产生一个包含N个x副本的数组。x的类型必须是Copy
  • 包含每个元素的列表,即[x, y, z]

允许空的固定数组[expr, 0],但是,这仍然会计算expr,并立即删除结果值,因此要注意副作用

数组强制为切片([T]),因此可以在数组上调用切片方法。 实际上,这提供了用于处理数组的大多数API。 切片具有动态大小,并且不强制转换为数组。可以使用切片模式将元素移出数组。如果需要一个元素,请参见mem::replace

1.1 数组的方法

  • 数组可以转换成按值引用的迭代器(iter)和按值的迭代器(into_iter)
  • array.map()生成一个新的数组
  • zip:把两个数组组合成一个数组
  • as_slice:把全数组转换成一个只读/可写的切片
    • 可以使用切片的各个方法
  • each_ref: 生成一个新的借用各元素的数组

1.2 实现的特性

2. bool类型

2.1 方法

2.2 特性

3. 字符

char类型表示单个字符。 更具体地说,由于“字符”不是Unicode中定义明确的概念,因此char是“Unicode标量值”,与“Unicode代码点”相似但不相同。char始终为四个字节

3.1 字符的方法

3.2 实现的特性

char类型通过实现的特性可以进行如下的操作:

4. f32/f64

浮点类型的值,另外f32可以表示一些特殊的值:

  • -0
    • 这只是由于浮点数的编码方式
    • 它在语义上等同于0,而-0.0 == 0.0结果为true
  • −∞
    • 这些是通过1.0 / 0.0之类的计算得出的
  • NaN(not a number)
    • 该值来自(-1.0).sqrt()这样的计算
    • NaN有一些潜在的意外行为:
      • 它不等于任何浮点数,包括它自己!
      • 它既不小于也不大于任何浮点数,因此不可能进行排序。
      • 最后,它被认为是具有传染性的,其中一个操作数是NaN,其结果也会是NaN

4.1 自身的方法

f32method

4.2 实现的特性

5. 函数指针fn

普通函数指针是通过强制转换普通函数或不捕获环境的闭包来获得的:

fn add_one(x: usize) -> usize {
    x + 1
}

let ptr: fn(usize) -> usize = add_one;
assert_eq!(ptr(5), 6);

let clos: fn(usize) -> usize = |x| x + 5;
assert_eq!(clos(5), 10);

5.1 ABI

最重要的是,函数指针可以根据它们使用的ABI而变化。这是通过在类型之前添加extern关键字,然后是相关ABI来实现的。默认ABI是Rust,即fn()extern "Rust" fn()是完全相同的类型。指向带有C ABI的函数的指针类型为extern "C" fn()

extern "ABI" {…}块使用ABI声明函数。这里默认是C语言,也就是说,函数声明在extern {…}块具有C ABI。

5.2 Trait

函数指针实现以下特征,由于Rust类型系统的临时限制,这些特性只在带12个或更少参数的函数上实现,使用“Rust”和“C”abi:

  • Clone
  • PartialEq
  • Eq
  • PartialOrd
  • Ord
  • Hash
  • Pointer
    • fmt
    • {:p}实现打印
  • Debug

6. i32/isize/usize 整型

6.1 方法

i32method

6.2 实现的Trait

  • 算术
    • +, -, *, /运算
    • <<, >>运算
    • &, |, ^, &=, |=, ^=
    • ==, !=
    • >, ==, <
    • 累乘:Product
    • 取负-, 取反!,取余%
    • Default::default(): 0
    • Hash值
  • 打印
    • Binary: {:#b}
    • Debug: {:?}
    • Display: {}
    • LowerExp: {:e}
    • LowerHex: {:x}, {:#x}
    • Oct: {:o}, {:#o}
  • 拷贝
    • Copy
    • Clone
  • 转换
    • From, From
    • FromStr
  • 步进Step
    • steps_between
    • forward_(un)checked
    • backward_(un)checked

7. 切片

对连续序列[T]的动态大小视图。 这里的连续意味着元素的布局应使每个元素与其相邻元素之间的距离相同。

切片是一个以指针和长度表示的内存块的视图

切片可以是可变的,也可以是共享的。共享片类型是&[T],而可变片类型是&mut [T],其中T表示元素类型。例如,您可以改变可变切片所指向的内存块

let mut x = [1, 2, 3];
let x = &mut x[..]; // Take a full slice of `x`.
x[1] = 7;
assert_eq!(x, &[1, 7, 3]);

7.1 方法

附录

Any 特性

Rust提供了运行时反射的能力。因为 Rust 不带 VM 不带 Runtime ,因此,其提供的反射更像是一种编译时反射。因为,Rust只能对 ‘static 生命周期的变量(常量)进行反射!

java反射机制是在运行状态中,对于任意一个类都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的属性和方法;这种动态获取类的信息以及动态调用对象的方法的功能。 简单说,反射机制指的就是程序在运行时能够获取自身的信息。 java反射机制的功能:

  1. 可以判断运行时的对象所属的类;
  2. 可以判断运行时对象所具有的成员变量和方法;
  3. 通过反射机制甚至可以调用对象的private方法
  4. 通过反射机制可以实例化类的对象。

举个例子

我们会有这样的需求,去某些路径里加载配置文件。我们可能提供一个配置文件路径,好吧,这是个字符串(String)。但是,当我想要传入多个配置文件的路径的时候怎们办?理所应当的,我们传入了一个数组。

use std::any::Any;
use std::fmt::Debug ;

fn load_config<T:Any+Debug>(value: &T) -> Vec<String>{
    let mut cfgs: Vec<String>= vec![];

    //由于我们无法判断出传入的参数类型,因此,只能从运行时候反射类型
    let value = value as &Any;

    // 类型推断
    // 如果类型推断成功,则 value 就会被转换成原来的类型
    match value.downcast_ref::<String>() {
        Some(cfp) => cfgs.push(cfp.clone()),
        None => (),
    };

    match value.downcast_ref::<Vec<String>>() {
        Some(v) => cfgs.extend_from_slice(&v),
        None =>(),
    }

    if cfgs.len() == 0 {
        panic!("No Config File");
    }
    cfgs
}

fn main() {
    let cfp = "/etc/wayslog.conf".to_string();
    assert_eq!(load_config(&cfp), vec!["/etc/wayslog.conf".to_string()]);
    let cfps = vec!["/etc/wayslog.conf".to_string(),
                    "/etc/wayslog_sec.conf".to_string()];
    assert_eq!(load_config(&cfps),
               vec!["/etc/wayslog.conf".to_string(),
                    "/etc/wayslog_sec.conf".to_string()]);
}