当前位置: 首页 > article >正文

Rust学习(二)——rust基础语法Ⅰ:

Rust学习(二)——rust基础语法Ⅰ:

1、关键字:

了解编程语言的同学都清楚,关键字在一门编程语言中的意义,所谓关键字就是语言的创造者及后续开发者们,以及定义好的具有特殊含义和作用的单词,需要注意的是在变量及函数等名命时要避开这些关键字,以避免可能出现逻辑冲突,每种编程语言所拥有的关键字数量并不相同,Rust目前有39个关键字:

Self	enum	match	super	as
extern	mod 	trait	async	false
move	true	await	fn   	mut
type	break	for		pub		union
const	if		ref		unsafe	continue
impl	return 	use		crate	in
self	where	dyn		let		static
while	else	loop	struct        # 注意Selfself是两个不同的关键字

很多关键字和其他编程语言种的关键字功能类似,比如:for,move,if等,但是也有一些独特的关键字,体现了语言的设计者的精妙构思,比如match在Rust种功能强大,但是在C/C++中对应的switch的功能就相对偏弱。

2、注释:

在编程中注释的作用自然不必多说,就有一句著名的格言展示了注释的重要性:一个程序员在编程时,只有他和上帝知道代码的作用,过了三天就只有上帝知道这段代码的作用了!(doge),因此在编程中加入注释,可以帮助阅读代码的人(也包括作者)更好的理解代码编写过程中的复杂逻辑,从而做出针对性的优化,Rust和C/C++、python等语言相比注释功能更加完整和强大!

Rust的注释有两大类:普通注释和文档注释。

①普通注释:

rust提供了单行和多行普通注释两种方法(和C/C++保持一样):

// 单行注释

/*
*
*多行注释
*多行注释
*
*/

②文档注释:

rust非常关注文档和测试,因此提供了专门的文档注释,用于在注释中直接编写文档和测试代码,同时Rust文档采用的时Markdown格式,因此在编写测试文档时,需要注意使用Markdown形式:

//! 生成库文档,用于说明整个模块的功能,一般置于模块开头
/// 生成库文档,用于说明函数和结构体功能,一般置于说明对象的开头

//! Math 模块
//!
/// #add 函数
/// 该函数为求和函数
///
/// # Example 
/// use math::add;
/// assert_eq!(3, add(1, 2));
fn add(x: i32, y: i32) -> i32 {
    // 求和
    x + y
}

3、Rust名命风格:

名命风格并不是强制要求,但是应该被看做时一种规范而被遵循。Rust推荐采用驼峰式命名(UpperCamelCase)来表示类级别的内容,而采用蛇形命名(snake_case)类描述值级别的内容,可见下表:

项						 约定
包						 snake_case
类型						UpperCamelCase
特性						UpperCamelCase						
枚举						UpperCamelCase
函数						snake_case
方法						snake_case
构造函数					(无特殊要求)或者new
转换函数					(无特殊要求)
宏						snake_case
局部变量					SCREAMING_SNAKE_CASE
静态变量					SCREAMING_SNAKE_CASE
常量						sanke_case
类型参数					UpperCamelCase
生命周期					lowercase

下面这个例子给大家提供了一个很好的参考:

// 枚举
enum Result<T,E> {
    Ok(T),
    Err(E),
}
// 特性trait
pub trait From<T> {
    fn from<T> -> Self;
}
// 结构体:
struct Rectangle {
    height: i32,
    width: i32,
}
impl Rectangle {
    //构造函数
    fn new(height: i32, width: i32) ->Self {
        Self {height, width}
    }
    
    // 函数
    fn calc_area(&self) ->i32 {
        self.height * self.width
    }
}

// 静态变量和常量
static NAME: &str = "kew";
const AGE: i32 = 25;

// 宏定义:
macro_rules! add{
    ($a:expr, $b:expr) => {
        {
            $a + $b
        }
    }
}

// 变量及宏使用:
let sum_of_nums = add!(1,2);

4、常量:

Rust中的常量和C++中的常量基本一致,特点是不可修改,不可覆盖,使用const关键字定义:

//常量定义,类似于C/C++中的#define(宏定义)
const AGE: i32 = 1984;
// AGE = 1985; 报错, 常量不允许被修改
// const AGE: i32 = 1996; 报错,AGE已经被定义过,不能被覆盖

5、变量:

rust中变量使用let定义,变量是一个绑定到一个名称且允许改变(可覆盖)的值,但在Rust中有一些不同,默认直接使用let定义的变量不可修改,使用mut关键字方可修改:

let x: f64 = 3.14;
// x = 6.28; 报错,变量不可修改
let x: f64 = 6.28; //变量可以被覆盖

let mut y: f64 = 256.01;
y = 3.28;
let y: f64 = 2024; // 使用mut关键字之后变量可修改,可覆盖。

6、静态变量:

静态变量是一种特殊的变量,可以被修改,但是不能被覆盖,同时其是否可修改同样取决于是否使用mut关键字:

static NAME: &str = "rust";
// NAME = "new"; 报错,未使用mut不可以被改变
static mut NUM: i32 = 12;
unsafe {
    NUM += 1;  // 可以看到static mut 修改是在unsafe中完成的,所以日常开发中使用较少
}
// static NAME: &str = "Cargo"; 报错,静态变量不可覆盖
// static NUM: i32 = 13; 错误,静态变量不可覆盖

7、数据类型:

学习一门编程语言,一定会从数据类型入手,这点就好比学习C语言的char、array类型,python的整型、浮点型等,如果学习一门编程语言却不知道数据类型,未免太不专业了!

数据类型是一门语言的基础,所有复杂的模块都是由基础数据类型构建而来的,Rust的基础数据类型分为标量类型和符合类型两大类型,标量类型代表一个单独的值,复合类型则是将多个值组合成一个值的类型(有点绕,不要着急,下文会仔细解释!)

(1)标量类型:

Rust中有四种基本的标量类型:整型、浮点型、布尔型和字符型。

①整型:

整型即整数:没有小数部分的的数字,根据长度和符号,可分为12类,其中i表示有符号整型,u表示无符号整型:

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

这里需要特别指出,isize和usize是指和计算机架构相匹配的整型长度,如64位机器isize和usize都是64位长度,32位机器isize和usize都是32位长度的。

②浮点数:

rust中的浮点数分为:f32和f64两种类型(都是有符号的),默认为64位。

③布尔类型:

和其他类型一致,都是true和false两类(doge)。

④字符型:

rust的字符和C语言中的char是一致的,注意:字符使用单引号声明,而字符串使用双引号声明,字符串属于数组类型。

// Unicode 标量:字符型
let c = 'a';
// 数组字符串:
let str_c = "hello rust";

(2)复合类型:

①元组:

元组是一种能够将多个类型的数据值组合成复合值得类型,即所谓将多个值合并为一个值。一旦声明元组得长度就不可改变,元组使用圆括号包裹,并用逗号分隔。为了从元组中获取值,你可以使用模式匹配和点符号(类似于其他语言得索引,从下标0开始)。

let tup: (i32, i32,i64) = (1, 2, 3);

// 使用模式匹配:
let (x, y, z) = tup;

let tup2:(i32, i32, i32) = (2,3,4);
let zero = tup2.0 // 点符号获取值
②数组:

Rust中得数组和C/C++中得数组类似,数组中得每一个元素必须保持一致,且长度也不可以改变。但是Rust为我们提供了可变数组,使用Vec定义得数组,允许增长长度,大部分时候,我们使用得也是Vec定义得数组:

// 定义数组
let numbers = ["a", "b", "c"];
let digits[i32;5] = [0, 1, 2, 3, 4, 5]; // 通过[type;num]定义数组
let zeros = [0;5]; //创建一个包含5个0得数组

let bundary = numbers[0];

(3)数据类型转换:

Rust中得数据类型大多数是可以互相转换得,比如将i8转换为i16就是合理转换,但rust中不支持原生类型之间得隐式转换(将字符型转换为浮点型),必须使用as关键字进行显性转换。

fn main() {
    let decimal:f32 = 61.234;
    // let integer: u32 = decimal; 错误!不能进行隐式转换
    let integer = decimal as u32; //正确!,使用as进行显示转换
}

更加复杂得类型中,Rust提供了From和Info两个trait进行转换:(trait是一个难点,后面会具体介绍)

pub trait From<T> {
    fn from<T> ->Self;
}
pub trait Into<T> {
    fn into<T> ->Self;
}

struct Complex {
    real:i32,
    imag:i32
}

impl From<i32> for Complex {
    fn from(real:i32) ->Self {
        Self {real, imag:0}
    }
}

fn main() {
    let c1: Complex = Complex::from(2);
    let c2: Complex = 2.into();
    println!("c1:{:?}, c2:{:?}", c1, c2);
}

http://www.kler.cn/a/389577.html

相关文章:

  • 去地面算法——depth_clustering算法调试(1)
  • Rust 建造者模式
  • GitHub Org
  • PYNQ 框架 - 中断(INTR)驱动
  • EasyExcel 使用多线程按顺序导出数据
  • NCC前端调用查询弹框
  • 【数据分享】2024年我国省市县三级的生活服务设施数量(46类设施/Excel/Shp格式)
  • 大数据实训室中,高职大数据可视化开发技术实训课程改革研究
  • 【机器学习】强化学习(1)——强化学习原理浅析(区分强化学习、监督学习和启发式算法)
  • 蓝桥杯-洛谷刷题-day2(C++)
  • Linux系统程序设计--2. 文件I/O
  • 大模型系列——LLAMA-O1 复刻代码解读
  • Spring Boot 的生命周期
  • 【进阶】Stable Diffusion 插件 Controlnet 安装使用教程(图像精准控制)
  • 探密 C++ STL — 深入理解 Stack 和 Queue 的实现与应用
  • 前端上传大文件,后端报错Content-Type ‘application/octet-stream‘ is not supported【解决】
  • Spring Boot2.x教程:(十二)日志分割后续
  • #渗透测试#SRC漏洞挖掘#Python自动化脚本的编写04之通过面向对象编程学生管理信息系统01
  • 20241108,LeetCode 每日一题,用 Go 计算字符串中最长无重复字符
  • 创元集团携手火山引擎,数据飞轮驱动美妆品牌数字化转型
  • 一个基于Zookeeper+Dubbo3+SpringBoot3的完整微服务调用程序示例代码
  • C语言中,“extern”关键字的含义与用法
  • 网页版五子棋——用户模块(服务器开发)
  • 金山云C++面试题及参考答案
  • jenkins配置前端自动部署
  • MSB8041此项目需要 MFC 库。从 Visual Studio 安装程序(单个组件选项卡)为正在使用的任何工具集和体系结构安装-错误解决