0
点赞
收藏
分享

微信扫一扫

DeepBIO:一个自动化和可解释的深度学习平台,用于高通量生物序列预测,功能注释和可视化分析

以沫的窝 2023-06-23 阅读 26

文章目录


在这里插入图片描述

0 引入

在这里我们需要介绍Rust和数据结构有点关系的语法,如结构体、枚举以及集合。


1、结构体

1. 1 结构体

结构体字C语言中是很重要概念,Rust 中的结构体(Struct)与元组(Tuple)都可以将若干个类型不一定相同的数据捆绑在一起形成整体,但结构体的每个成员和其本身都有一个名字,这样访问它成员的时候就不用记住下标了。元组常用于非定义的多值传递,而结构体用于规范常用的数据结构。结构体的每个成员叫做"字段"。。

//定义一个结构体
struct Animal{
    name: String,             //后面是,而不是;
    size: u32,
    belong: String,
    home: String
}

//实例化
let dog = Animal{
    name: String::from("dog")
    size: 15,
    belong: String::from("I"),
    home: String::from("Anhui")
}


//结构体可以这么用
let name = String::from("dog");
let belong= String::from("I");
let dog= Animal {
    name,
    size: 15,
    belong,
    home: String::from("Anhui")
};

//输出结构体

#[derive(Debug)]
fn main() {
    let dog2 = Animal{
	    name: String::from("dog2")
	    size: 15,
	    belong: String::from("I"),
	    home: String::from("Anhui")
    }

    println!("rect1 is {:?}", dog2 );    //如果属性较多的话可以使用另一个占位符 {:#?} 。

注:

  • 不能声明实例,结尾不需要 ; 符号,而且每个字段定义之后用 , 分隔。
  • 实例化结构体的时候用 JSON 对象的 key: value 语法来实现定义。
  • 一定要导入调试库 #[derive(Debug)] ,之后在 println 和 print 宏中就可以用 {:?} 占位符输出一整个结构体:

也可以使用一个结构体去初始化另一个结构体,但是与C语言不一样的是,就是这两个结构体不能完全一样,至少有一个字段不一样,如下:

let dog= Animal {
    name,
    size: 15,
    belong,
    home: String::from("Anhui")
};

let cat = Animal{
    name = String::from("cat")
    ..dog                        //注意格式
}


1. 2 结构体方法

Rust 语言不是面向对象的,但是面向对象的珍贵思想可以在 Rust 实现。
结构体方法的第一个参数必须是 &self,不需声明类型,因为 self 不是一种风格而是关键字。
在调用结构体方法的时候不需要填写 self ,这是出于对使用方便性的考虑。

struct Rectangle {
    width: u32,
    height: u32,
}
   
impl Rectangle {
    fn area(&self) -> u32 {
        self.width * self.height
    }
}

fn main() {
    let rect1 = Rectangle { width: 30, height: 50 };
    println!("rect1's area is {}", rect1.area());
}



//上述也可以这么实现
impl Rectangle {
    fn create(width: u32, height: u32) -> Rectangle {
        Rectangle { width, height }
    }
}
fn main() {
    let rect = Rectangle::create(30, 50);  //结构体关联函数,在impl块中省略&self,但是在用的时
                           			       //  候需要声明
    println!("{:?}", rect);
}

1. 3 元组结构体

有一种更简单的定义和使用结构体的方式:元组结构体。
元组结构体是一种形式是元组的结构体。
与元组的区别是它有名字和固定的类型格式。它存在的意义是为了处理那些需要定义类型(经常使用)又不想太复杂的简单数据:

struct Color(u8, u8, u8);
struct Point(f64, f64);

let black = Color(0, 0, 0);
let origin = Point(0.0, 0.0);

元组结构体每个对象可以像结构体那样用下标去访问

  println!("black = ({}, {}, {})", black.0, black.1, black.2);

2、枚举类

2.1 match

枚举类在 Rust 中并不像其他编程语言中的概念那样简单,有着自己不一样的概念和用法,枚举的目的是对某一类事物的分类,分类的目的是为了对不同的情况进行描述。基于这个原理,往往枚举类最终都会被分支结构处理(许多语言中的 switch )
定义一个简单的枚举

enum Book {
    Papery(u32),                 //纸质书   
    Electronic(String)           //电子书
}
fn main() {
    enum Book {
        Papery {index: u32},
        Electronic {url: String},
    }
   
    let book = Book::Papery{index: 1001};
    let ebook = Book::Electronic{url: String::from("url...")};
   
    match book {
        Book::Papery { index } => {
            println!("Papery book {}", index);
        },
        Book::Electronic { url } => {
            println!("E-book {}", url);
        }
    }
}

2.2 Option 枚举类

Option 是 Rust 标准库中的枚举类,这个类用于填补 Rust 不支持 null 引用的空白。

enum Option<T> {
    Some(T),
    None,
}

使用方法

fn main() {
    let opt = Option::Some("Hello");
    match opt {
        Option::Some(something) => {
            println!("{}", something);
        },
        Option::None => {
            println!("opt is nothing");
        }
    }
}

//省略Option 简介写法

fn main() {
        let t = Some(64);
        match t {
                Some(64) => println!("Yes"),
                _ => println!("No"),
        }
}

// 也可以用 if let 语法再一次简洁,有点语法糖的感觉
fn main() {
    enum Book {
        Papery(u32),
        Electronic(String)
    }
    let book = Book::Electronic(String::from("url"));
    if let Book::Papery(index) = book {
        println!("Papery {}", index);
    } else {
        println!("Not papery book");
    }
}


3、集合

集合(Collection)是数据结构中最普遍的数据存放形式,Rust 标准库中提供了丰富的集合类型帮助开发者处理数据结构的操作。

3.1 向量(Vector)

向量(Vector)是一个存放多值的单数据结构,该结构将相同类型的值线性的存放在内存中。
向量是线性表,在 Rust 中的表示是 Vec。
向量的使用方式类似于列表(List),我们可以通过这种方式创建指定类型的向量:

let vector: Vec<i32> = Vec::new(); // 创建类型为 i32 的空向量
let vector = vec![1, 2, 4, 8];     // 通过数组创建向量

vector.push(16);                    //追加
    let mut v1: Vec<i32> = vec![1, 2, 4, 8];
    let mut v2: Vec<i32> = vec![16, 32, 64];
    v1.append(&mut v2);              //拼接
             

取出数据使用 get,当然也可以像数组那样,使用下标(注意越界)

fn main() {
    let mut v = vec![1, 2, 4, 8];
    println!("{}", match v.get(0) {
        Some(value) => value.to_string(),
        None => "None".to_string()
    });
}
             

3.2 字符串(String)

字符串的使用和C差不多,很方便可以作为各种数据的转换,拼接,切片等

let string = String::new();

let one = 1.to_string();         // 整数到字符串

let hello = String::from("Hello");

let mut s = String::from("run");
s.push_str("oob");             // 追加字符串切片
s.push('!');                   // 追加字符
             

3.1 映射表(Map)

映射表(Map)在其他语言中广泛存在。其中应用最普遍的就是键值散列映射表(Hash Map)。

use std::collections::HashMap;

fn main() {
    let mut map = HashMap::new();
    map.insert("color", "red");
    map.insert("size", "10 m^2");
    println!("{}", map.get("color").unwrap());

     //遍历打印

	    for p in map.iter() {
        println!("{:?}", p);
    }
}

map中如果在insert有相同的数据,则会覆盖掉原先数据,如果想安全插入

map.entry("color").or_insert("red");

4、总结

关于数据结构这块,Rust能够使用部分的数据结构,在枚举这一块稍微不一样。

举报

相关推荐

0 条评论