首页 > 其他分享 >【rust】《Rust深度学习[1]-科学计算库(Ndarray)》

【rust】《Rust深度学习[1]-科学计算库(Ndarray)》

时间:2024-04-23 13:22:06浏览次数:15  
标签:数组 let Rust arr1 Ndarray println prelude rust ndarray

什么是Ndarray?

ndarray是Rust生态中用于处理数组的库。它包含了所有常用的数组操作。简单地说ndarray相当于Rust版本的numpy。

ndarray生态系统中crate的文档:

ndarray 基础库

ndarray-rand 随机数生成库

ndarray-stats 统计方法

  顺序统计(最小、最大、中值、分位数等);

  汇总统计(平均值、偏斜度、峰度、中心矩等)

  分区;

  相关分析(协方差、皮尔逊相关);

  信息论的度量(熵、KL散度等);

  偏差函数(距离、计数、误差等);

  直方图计算。

ndarray-npy 多维数组的存储与加载

ndarray-linalg 线性代数相关函数

为什么需要Ndarray?

ndarray是专门为处理n维数组(矩阵)而设计的,里面包含了很多数学运算,比如矩阵相乘、矩阵求逆等。

其次,ndarray支持SIMD(Single Instruction Multiple Data),可以进一步提升计算性能。

SIMD 的全称是 Single Instruction Multiple Data,中文名“单指令多数据”。顾名思义,一条指令处理多个数据。

如上图所示

(a)是普通的标量计算,加法指令一次只能对两个数执行一个加法操作。

(b)是SIMD向量计算,SIMD加法指令一次可以对两个数组(向量)执行加法操作。

导入依赖库

[dependencies]
ndarray = "0.15.6"

数组创建

创建数组

// 导入ndarray库
use ndarray::prelude::*;

fn main(){
    // 创建数组
    let arr1 = array![1.,2.,3.,4.,5.];
    println!("{}", arr1);
}

创建阵列值

// 导入ndarray库
use ndarray::prelude::*;

fn main(){
    // 创建阵列值
    // range有三个参数分别是:起始值, 范围结束值(不包含), 步长
    let arr1 = Array::range(0., 10., 0.5);
    println!("{}", arr1);
}

创建指定个数的范围均值

// 导入ndarray库
use ndarray::prelude::*;

fn main(){
    // 创建指定个数的范围值
    // linspace有三个参数分别是:起始值, 范围结束值(包含), 个数
    // 重点:个数超出范围的总个数时,数值就会生成错误
    let arr1 = Array::linspace(0., 10., 6); // [0, 2, 4, 6, 8, 10]  
    let arr2 = Array::linspace(0., 10., 3); // [0, 5, 10] 
    println!("{}", arr1);
    println!("{}", arr2);
}

创建用1填充的多维数组

// 导入ndarray库
use ndarray::prelude::*;

fn main(){
    // 创建一维或多维数组,填充数值为 1 
    // ones的主要参数可以是一个整数,表示创建一维数组,也可以是一个元组,表示创建多维数组
    let arr1: ArrayBase<OwnedRepr<i32>, _> = Array::ones((3, 4, 5));
    println!("{}", arr1);
}

// 输出结果
// 一维数组包含3组数组
// 二维数组包含4组数组
// 三维数组包含5个元素
/*
[[[1, 1, 1, 1, 1], 
  [1, 1, 1, 1, 1], 
  [1, 1, 1, 1, 1], 
  [1, 1, 1, 1, 1]],
                   
 [[1, 1, 1, 1, 1], 
  [1, 1, 1, 1, 1], 
  [1, 1, 1, 1, 1], 
  [1, 1, 1, 1, 1]],
                   
 [[1, 1, 1, 1, 1], 
  [1, 1, 1, 1, 1], 
  [1, 1, 1, 1, 1], 
  [1, 1, 1, 1, 1]]]
*/

创建用0填充的多维数组

// 导入ndarray库
use ndarray::prelude::*;

fn main(){
    // 创建一维或多维数组,填充数值为 0 
    // zeros的主要参数可以是一个整数,表示创建一维数组,也可以是一个元组,表示创建多维数组
    let arr1: ArrayBase<OwnedRepr<i32>, _> = Array::zeros((3, 4, 5));
    println!("{}", arr1);
}

// 输出结果
// 一维数组包含3组数组
// 二维数组包含4组数组
// 三维数组包含5个元素
/*
[[[0, 0, 0, 0, 0],
  [0, 0, 0, 0, 0], 
  [0, 0, 0, 0, 0], 
  [0, 0, 0, 0, 0]],
                   
 [[0, 0, 0, 0, 0], 
  [0, 0, 0, 0, 0], 
  [0, 0, 0, 0, 0], 
  [0, 0, 0, 0, 0]],
                   
 [[0, 0, 0, 0, 0], 
  [0, 0, 0, 0, 0], 
  [0, 0, 0, 0, 0], 
  [0, 0, 0, 0, 0]]]
*/

创建用0填充的多维数组(设置内存排列方式)

// 导入ndarray库
use ndarray::prelude::*;

fn main(){
    // 创建一维或多维数组,填充数值为 0 
    // zeros的主要参数可以是一个整数,表示创建一维数组,也可以是一个元组,表示创建多维数组
    // 设置数组元素在内存中的排列顺序,可选参数,可以是 .c()(按行排列)或 .f()(按列排列)
    let arr1: ArrayBase<OwnedRepr<i32>, _> = Array::zeros((3, 4, 5).f());
    println!("{}", arr1);
}

// 输出结果
// 一维数组包含3组数组
// 二维数组包含4组数组
// 三维数组包含5个元素
/*
[[[0, 0, 0, 0, 0],
  [0, 0, 0, 0, 0], 
  [0, 0, 0, 0, 0], 
  [0, 0, 0, 0, 0]],
                   
 [[0, 0, 0, 0, 0], 
  [0, 0, 0, 0, 0], 
  [0, 0, 0, 0, 0], 
  [0, 0, 0, 0, 0]],
                   
 [[0, 0, 0, 0, 0], 
  [0, 0, 0, 0, 0], 
  [0, 0, 0, 0, 0], 
  [0, 0, 0, 0, 0]]]
*/

数组置0操作

// 导入ndarray库
use ndarray::prelude::*;

fn main(){
    // 创建多维数组
    let arr1 = array![[1,2,3], [4,5,6], [7,8,9]];
    println!("arr7 : \n{}", arr1);

    // 将多维数组内的元素重置为0
    let arr2:ArrayBase<OwnedRepr<i32>, _> = Array::zeros(arr1.raw_dim());
    println!("置零后 : \n{}", arr2);
}

创建指定元素的多维数组

// 导入ndarray库
use ndarray::prelude::*;

fn main(){
    // 创建指定元素 7 的多维数组
    let arr1 = Array::from_elem((3,4), 7.);
    println!("{}", arr1);
}

/*
[[7, 7, 7, 7],
 [7, 7, 7, 7],
 [7, 7, 7, 7]]
*/

创建单位矩阵

单位矩阵是个方阵,从左上角到右下角的对角线(称为主对角线)上的元素均为1;除此以外全都为0。

// 导入ndarray库
use ndarray::prelude::*;

fn main(){
    // 创建 4 * 4 的单位矩阵
    let arr1:ArrayBase<OwnedRepr<i32>, _> = Array::eye(4);
    println!("{}", arr1);
}

/*
[[1, 0, 0, 0],
 [0, 1, 0, 0],
 [0, 0, 1, 0],
 [0, 0, 0, 1]]
*/

列表转多维数组

// 导入ndarray库
use ndarray::prelude::*;

fn main(){
    // 通过Vec的数据 创建 2 * 2 * 2 的矩阵
    let arr1:ArrayBase<OwnedRepr<i32>, _> = Array::from_shape_vec(
        // 设置数组元素在内存中的排列顺序,可选参数,可以是 .c()(按行排列)或 .f()(按列排列)
        (2,2,2).f(), 
        vec![1,2,3,4,5,6,7,8]
    ).unwrap();
    println!("{}", arr1);
}

/*
[[[1, 5],
  [3, 7]],
  
 [[2, 6], 
  [4, 8]]]
*/

索引与切片

访问一维数组最后一位元素

// 导入ndarray库
use ndarray::prelude::*;

fn main(){
    let arr1 = array![1,2,3,4,5,6];
    // 长度减一
    println!("{}", arr1[arr1.len() - 1]);
}

取多维数组某行某列的值元素

重点:如果取值的位置是个数组,则取值报错。

// 导入ndarray库
use ndarray::prelude::*;

fn main(){
    let arr1 = array![
        [1,2,5],
        [8,14,23],
        [37,45,53]
    ];
    println!("{}", arr1[[1, 2]]); // 输出为:23
}

取多维数组某行某列的数组或值元素

重点:如果取值的位置是个数组,也可以取到数据。

// 导入ndarray库
use ndarray::prelude::*;

fn main(){
    // 这里是不可变数组
    let arr1 = array![
         [[17, 8, 7, 7, 7],
          [27, 8, 7, 7, 7],
          [37, 8, 7, 7, 7],
          [47, 8, 7, 7, 7]],

         [[57, 8, 7, 7, 7],
          [67, 8, 7, 7, 7],
          [77, 8, 7, 7, 7],
          [87, 8, 7, 7, 7]],

         [[97, 8, 7, 7, 7],
          [107, 8, 7, 7, 7],
          [117, 8, 7, 7, 7],
          [127, 8, 7, 7, 7]]
    ];
    println!("列表值:\n{}", arr1);
    // 这里表示 取第一列下的所有数组下的所有数组(获取的是不可变数组)
    // .. 表示所有,可以指定下标位置获取指定行列值
    println!("取值:\n{}", arr1.slice(s![1, .., ..]));
    
    // 重点:如果想获取可变数据需要数组本身为 let mut 然后通过 .slice_mut 方法获取
}

/*
列表值:
[[[17, 8, 7, 7, 7], 
  [27, 8, 7, 7, 7], 
  [37, 8, 7, 7, 7], 
  [47, 8, 7, 7, 7]],
                    
 [[57, 8, 7, 7, 7], 
  [67, 8, 7, 7, 7], 
  [77, 8, 7, 7, 7], 
  [87, 8, 7, 7, 7]],
                    
 [[97, 8, 7, 7, 7], 
  [107, 8, 7, 7, 7],
  [117, 8, 7, 7, 7],
  [127, 8, 7, 7, 7]]]
  
取值:
[[57, 8, 7, 7, 7],
 [67, 8, 7, 7, 7],
 [77, 8, 7, 7, 7],
 [87, 8, 7, 7, 7]]
*/

取二维数组的某几行或某几个元素

// 导入ndarray库
use ndarray::prelude::*;

fn main(){
    let arr1 = array![
        [1,2,3,11,22,33],
        [4,5,6,44,55,66],
        [7,8,9,77,88,99]
    ];
    // 取二维数组的前两行
    // 从0下标开始取,范围到2下标(但是不包含结束的2下标数据)
    // .. 取全部,也可以指定下标位组成新数组
    // .. 前可以指定下标开始位,如:0..2   1..3
    println!("{}", arr1.slice(s![..2, ..]));
    
    // 取二维数组的后两行
    println!("{}", arr1.slice(s![-2.., ..]));

    // 取二维数组的前两行的2,3,4列
    println!("{}", arr1.slice(s![..2, 2..5]));

    // 取二维数组的前两行并将数值反序
    // -1就是反序排列
    println!("{}", arr1.slice(s![..2, ..;-1]));
}

数组维度与步长

获取数组维度

// 导入ndarray库
use ndarray::prelude::*;

fn main(){
    // 创建一个3维数组(3D数组)
    let arr1 = array![
         [[17, 8, 7, 7, 7],
          [27, 8, 7, 7, 7],
          [37, 8, 7, 7, 7],
          [47, 8, 7, 7, 7]],

         [[57, 8, 7, 7, 7],
          [67, 8, 7, 7, 7],
          [77, 8, 7, 7, 7],
          [87, 8, 7, 7, 7]],

         [[97, 8, 7, 7, 7],
          [107, 8, 7, 7, 7],
          [117, 8, 7, 7, 7],
          [127, 8, 7, 7, 7]]
    ];
    // 获取数组的维度
    println!("{}", arr1.ndim()); // 输出为:3
}

获取数组的总元素个数

// 导入ndarray库
use ndarray::prelude::*;

fn main(){
    // 创建一个3维数组(3D数组)
    let arr1 = array![
         [[17, 8, 7, 7, 7],
          [27, 8, 7, 7, 7],
          [37, 8, 7, 7, 7],
          [47, 8, 7, 7, 7]],

         [[57, 8, 7, 7, 7],
          [67, 8, 7, 7, 7],
          [77, 8, 7, 7, 7],
          [87, 8, 7, 7, 7]],

         [[97, 8, 7, 7, 7],
          [107, 8, 7, 7, 7],
          [117, 8, 7, 7, 7],
          [127, 8, 7, 7, 7]]
    ];
    // 获取数组的总元素个数
    println!("{}", arr1.len()); // 输出为:60
}

获取数组的维度结构

// 导入ndarray库
use ndarray::prelude::*;

fn main(){
    // 创建一个3维数组
    let arr1 = array![
         [[17, 8, 7, 7, 7],
          [27, 8, 7, 7, 7],
          [37, 8, 7, 7, 7],
          [47, 8, 7, 7, 7]],

         [[57, 8, 7, 7, 7],
          [67, 8, 7, 7, 7],
          [77, 8, 7, 7, 7],
          [87, 8, 7, 7, 7]],

         [[97, 8, 7, 7, 7],
          [107, 8, 7, 7, 7],
          [117, 8, 7, 7, 7],
          [127, 8, 7, 7, 7]]
    ];
    // 获取数组维度的结构
    println!("{:?}", arr1.shape()); 
    // 输出为数组:[3, 4, 5]
    // 表示:一维数组为3行,二维数组为4列,三维数组为5行

    // 另一种方式:获取数组维度的结构
    println!("{:?}", arr1.dim()); 
    // 输出为元组Vec:(3, 4, 5)
}

获取数组某层维度内的维度结构

// 导入ndarray库
use ndarray::prelude::*;

fn main(){
    // 创建一个3维数组 维度结构 [3, 4, 5]
    let arr1 = array![
         [[17, 8, 7, 7, 7],
          [27, 8, 7, 7, 7],
          [37, 8, 7, 7, 7],
          [47, 8, 7, 7, 7]],

         [[57, 8, 7, 7, 7],
          [67, 8, 7, 7, 7],
          [77, 8, 7, 7, 7],
          [87, 8, 7, 7, 7]],

         [[97, 8, 7, 7, 7],
          [107, 8, 7, 7, 7],
          [117, 8, 7, 7, 7],
          [127, 8, 7, 7, 7]]
    ];
    // 获取数组第0层维度的结构数
    println!("{}", arr1.len_of(Axis(0))); // 输出为 3
    
    // 获取数组第1层维度的结构数
    println!("{}", arr1.len_of(Axis(1))); // 输出为 4
    
    // 获取数组第2层维度的结构数
    println!("{}", arr1.len_of(Axis(0))); // 输出为 5
}

计算维度之间的步长(计算跨度字节数)

步长就是告诉我们必须在内存中跳过多少字节才能沿着某个轴移动到下一个位置,同一维度就可以看作为一个轴,如下示例:

// 导入ndarray库
use ndarray::prelude::*;

fn main(){
    // 创建一个三维数组
    let arr1 = array![
        [
            [1,2], 
            [3,4],
            [5,6]
        ],
        [
            [7,8],
            [9,10],
            [11,12]
        ],
        [
            [13,14],
            [15,16],
            [17,18]
        ]
    ];
    // 同维度下跨越同下标元素需要的步长(步幅)
    println!("{:?}", arr1.strides()); 
    // 输出为 [6, 2, 1]
    // 从一维轴计算跨度(跨越的元素个数)
    // 		即从下标为0的内部下标0的元素1 跨到 下标为1的内部下标0的元素7 需要跨越6个元素
    // 从二维轴计算跨度(跨越的元素个数)
    // 		即从下标为0的内部下标0的元素1 跨到 下标为1的内部下标0的元素3 需要跨越2个元素
    // 从三维轴计算跨度(跨越的元素个数)
    // 		即从下标为0的元素1 跨到 下标为1元素2 需要跨越1个元素
}

判断数组长度是否为零

// 导入ndarray库
use ndarray::prelude::*;

fn main(){
    // 创建一个三维数组
    let arr1 = array![
        [
            [1,2], 
            [3,4],
            [5,6]
        ],
        [
            [7,8],
            [9,10],
            [11,12]
        ],
        [
            [13,14],
            [15,16],
            [17,18]
        ]
    ];
    // 判断数组长度是否为0
    println!("{}", arr1.is_empty()); // 输出:false  表示数组长度不为0
}

多维数组的数学计算

基础运算

// 导入ndarray库
use ndarray::prelude::*;

fn main(){
    let arr16 = array![[1,2], [3,4]];
    let arr17 = array![[5,6], [6,7]];
    // 将同下标位的数进行相乘
    println!("{}", &arr16 * &arr17);
    /*
     [[5, 12],
     [18, 28]]
     */

    // 将同下标位的数进行相加
    println!("{}", &arr16 + &arr17);
    /*
     [[6, 8],
     [9, 11]]
    */
}

数组内所有元素的和

// 导入ndarray库
use ndarray::prelude::*;

fn main(){
    // 创建一个三维数组
    let arr1 = array![
        [
            [1,2], 
            [3,4],
            [5,6]
        ],
        [
            [7,8],
            [9,10],
            [11,12]
        ],
        [
            [13,14],
            [15,16],
            [17,18]
        ]
    ];
    // 数组内所有元素的总和
    println!("{}", arr1.sum());  // 171

}

沿数组轴求和

// 导入ndarray库
use ndarray::prelude::*;

fn main(){
    // 创建一个三维数组
    let arr1 = array![
        [
            [1,2], 
            [3,4],
            [5,6]
        ],
        [
            [7,8],
            [9,10],
            [11,12]
        ],
        [
            [13,14],
            [15,16],
            [17,18]
        ]
    ];
    // 数组某个维度(轴)所有元素的总和
    println!("{}", arr1.sum_axis(Axis(2)));  
    /*
     [[3, 7, 11],
     [15, 19, 23],
     [27, 31, 35]]
    */
}

沿数组轴求平均值

// 导入ndarray库
use ndarray::prelude::*;

fn main(){
    // 创建一个三维数组
    let arr1 = array![
        [
            [1.,2.], 
            [3.,4.],
            [5.,6.]
        ],
        [
            [7.,8.],
            [9.,10.],
            [11.,12.]
        ],
        [
            [13.,14.],
            [15.,16.],
            [17.,18.]
        ]
    ];
    // 数组某个维度(轴)的平均值
    println!("{}", arr1.mean_axis(Axis(2)).unwrap());
    /*
     [[1.5, 3.5, 5.5],
     [7.5, 9.5, 11.5],  
     [13.5, 15.5, 17.5]]
    */

    // 求 f64类型数组 整体的平均值
    // 平均值结果为 f64 类型
    println!("{}", arr1.sum() / a.len() as f64);
    // 9.5
}

数组操作

数组转置

// 导入ndarray库
use ndarray::prelude::*;

fn main(){
    let arr1 = array![
        [
            [1,2,12],
            [3,4,34],
            [5,6,56]
        ],
        [
            [7,8,78],
            [9,10, 90],
            [11,12, 23]
        ],
        [
            [13,14, 27],
            [15,16, 31],
            [17,18, 35]
        ]
    ];
    // 数组转置
    println!("{}", arr1.t());
}

/*
[[[1, 7, 13],
  [3, 9, 15],  
  [5, 11, 17]],
               
 [[2, 8, 14],  
  [4, 10, 16], 
  [6, 12, 18]],
               
 [[12, 78, 27],
  [34, 90, 31],
  [56, 23, 35]]]
*/

查看对角线

// 导入ndarray库
use ndarray::prelude::*;

fn main(){
    let arr1 = array![
        [
            [1,2,12],
            [3,4,34],
            [5,6,56]
        ],
        [
            [7,8,78],
            [9,10, 90],
            [11,12, 23]
        ],
        [
            [13,14, 27],
            [15,16, 31],
            [17,18, 35]
        ]
    ];
    // 查看对角线
    // 默认为:左上角 到 右下角
    println!("{}", arr1.diag());
    // [1, 10, 35]
}

修改数组全部元素为指定值

// 导入ndarray库
use ndarray::prelude::*;

fn main(){
    // 可变数组
    let mut arr1 = array![
        [
            [1,2,12],
            [3,4,34],
            [5,6,56]
        ],
        [
            [7,8,78],
            [9,10, 90],
            [11,12, 23]
        ],
        [
            [13,14, 27],
            [15,16, 31],
            [17,18, 35]
        ]
    ];
    // 所有元素都修改为 3
    arr1.fill(3);
    println!("{}", arr1);
}

/*
[[[3, 3, 3],
  [3, 3, 3], 
  [3, 3, 3]],
             
 [[3, 3, 3], 
  [3, 3, 3], 
  [3, 3, 3]],
             
 [[3, 3, 3], 
  [3, 3, 3], 
  [3, 3, 3]]]
*/

同维度数组覆盖

// 导入ndarray库
use ndarray::prelude::*;

fn main(){
    // 3*3 矩阵数组
    let arr1 = array![[1,2,3], [4,5,6], [7,8,9]];
    // 创建0填充的二维数组 3*3
    let mut arr2 = Array::zeros((3, 3));
    println!("复制前:\n{}", arr2);
    arr2.assign(&arr1);
    println!("复制后:\n{}", arr2);
}

/*
复制前:
[[0, 0, 0],
 [0, 0, 0],
 [0, 0, 0]]
复制后:   
[[1, 2, 3],
 [4, 5, 6],
 [7, 8, 9]]
*/

展开多维数组成一维数组

// 导入ndarray库
use ndarray::prelude::*;

fn main(){
    let arr1 = array![[1,2,3], [4,5,6], [7,8,9]];
    println!("{}", Array::from_iter(arr1.iter()));
    // [1, 2, 3, 4, 5, 6, 7, 8, 9]
}

迭代器

逻辑顺序迭代全部元素

// 导入ndarray库
use ndarray::prelude::*;

fn main(){
    let arr1 = array![[1,2,3], [4,5,6], [7,8,9]];
    for item in arr1.iter() {
        println!("iter: {}", item);
    }
}
/*
iter: 1
iter: 2                
iter: 3                
iter: 4                
iter: 5                
iter: 6                
iter: 7                
iter: 8                
iter: 9 
*/

维度迭代展示子视图

// 导入ndarray库
use ndarray::prelude::*;

fn main(){
    let arr1 = array![[1,2,3], [4,5,6], [7,8,9]];
    for item in arr1.outer_iter() {
        println!("outer_iter: {}", item);
    }
}
/*
outer_iter: [1, 2, 3]
outer_iter: [4, 5, 6]
outer_iter: [7, 8, 9]
*/

平面迭代并展示索引维度

// 导入ndarray库
use ndarray::prelude::*;

fn main(){
    let arr1 = array![[1,2,3], [4,5,6], [7,8,9]];
    for (index, item) in arr1.indexed_iter() {
        println!("indexed_iter: {:?}, {}", index, item);
    }
}
/*
indexed_iter: (0, 0), 1
indexed_iter: (0, 1), 2
indexed_iter: (0, 2), 3
indexed_iter: (1, 0), 4
indexed_iter: (1, 1), 5
indexed_iter: (1, 2), 6
indexed_iter: (2, 0), 7
indexed_iter: (2, 1), 8
indexed_iter: (2, 2), 9
*/

二维阵列常用方法

判断是否为正方形

// 导入ndarray库
use ndarray::prelude::*;

fn main(){
    let arr1 = array![[1,2,3], [4,5,6], [7,8,9]];
    println!("{}", arr1.is_square());
    // true
}

标签:数组,let,Rust,arr1,Ndarray,println,prelude,rust,ndarray
From: https://www.cnblogs.com/-CO-/p/18152666

相关文章

  • three.js使用Instanced Draw+Frustum Cull+LOD来渲染大场景(开源)
    大家好,本文使用three.js实现了渲染大场景,在移动端也有较好的性能,并给出了代码,分析了关键点,感谢大家~关键词:three.js、InstancedDraw、大场景、LOD、FrustumCull、优化、Web3D、WebGL、开源代码:Github我正在承接Web3D数字孪生项目,具体介绍可看承接各种Web3D业务加QQ群交流:106......
  • vim配置rust开发环境
    vim配置需要环境首先需要安装rust,然后安装rust-analysis,还需要nodejs,npm。插件使用vim-plug管理,也是需要提前安装的安装coc之后还需要安装CocInstallcoc-rust-analysis下边是踩坑出来的配置文件"插件安装在callplug#begin('~/.vim/plugged')和callplug#end()之间。cal......
  • Windows快速安装Rust
    本文是最简最快最小化安装重点提示:如果不想安装VS消耗时间和6-8G的空间,可以按本文安装。如果系统中已经安装了VS,那么直接运行rustup-init安装Rust,并一路回车即可。前置条件:安装C++环境rust底层是依赖C环境的连接器,所以需要先安装C/C++编译环境,点击下载64位mingw-builds......
  • The Stack and the Heap栈与堆__Rust
    Manyprogramminglanguagesdon’trequireyoutothinkaboutthestackandtheheapveryoften.许多编程语言并不会要求你经常思考堆栈。ButinasystemprogramminglanguagelikeRust,whetheravalueisonthestackortheheapaffectshowthelanguagebehaves......
  • rust程序中设置和访问环境变量
    在项目中,我们通常需要设置一些环境变量,用来保存一些凭证或其它数据,这时我们可以使用dotenv这个crate。1、添加crate依赖首先在项目中添加dotenv这个依赖:  2、添加.env文件在开发环境下,我们可以在项目根目录下创建和编辑.env这个文件: 在运行环境下,这个.env文件要......
  • 50个Rust新手常犯的错误:看看你中过几条?
    错误地使用可变和不可变借用letmutdata=vec![1,2,3];letx=&data[0];data.push(4);println!("{}",x);不能在有不可变引用时修改数据。忘记处理Optionfnmain(){letsome_number=Some(5);letsum=some_number+5;//错误:Option类型不能这......
  • Rust简易入门(六)
    Trait特质Trait是一种定义方法签名的机制,特质允许你定义一组方法的签名,但可以不提供具体的方法实现任何类型都可以实现特质,只要他们提供了特质中定义的所有方法。这是的你可以为不同类型提供相同的行为内置常量:const,整个生命周期都是有效的默认实现多重实现:类型可以实......
  • [Rust] Intro Lifetimes
    Thefollowingcodehascompilererror:fnjazz(years:&[i64])->Releases{leteighties:[i64]=&years[0..2];letnineties:[i64]=&years[2..4];Releases{years,eighties,nineties,}}let......
  • rust和内部可变性模式RefCell<T>
    内部可变性(Interiormutability)是Rust中的一个设计模式,它允许你即使在有不可变引用时也可以改变数据,这通常是借用规则所不允许的。为了改变数据,该模式在数据结构中使用 unsafe 代码来模糊Rust通常的可变性和借用规则。不安全代码表明我们在手动检查这些规则而不是让编译器替......
  • rust引用计数智能指针Rc<T>
    大部分情况下所有权是非常明确的:可以准确地知道哪个变量拥有某个值。然而,有些情况单个值可能会有多个所有者。例如,在图数据结构中,多个边可能指向相同的节点,而这个节点从概念上讲为所有指向它的边所拥有。节点在没有任何边指向它从而没有任何所有者之前,都不应该被清理掉。为了启用......