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

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

1、关键字:

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

rust 复制代码
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        # 注意Self和self是两个不同的关键字

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

2、注释:

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

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

①普通注释:

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

rust 复制代码
// 单行注释

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

②文档注释:

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

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

//! 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)类描述值级别的内容,可见下表:

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

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

rust 复制代码
// 枚举
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关键字定义:

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

5、变量:

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

rust 复制代码
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关键字:

rust 复制代码
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表示无符号整型:

rust 复制代码
长度		有符号		无符号
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是一致的,注意:字符使用单引号声明,而字符串使用双引号声明,字符串属于数组类型。

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

(2)复合类型:

①元组:

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

rust 复制代码
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定义得数组:

rust 复制代码
// 定义数组
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关键字进行显性转换。

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

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

rust 复制代码
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);
}
相关推荐
SoraLuna12 分钟前
「Mac玩转仓颉内测版7」入门篇7 - Cangjie控制结构(下)
算法·macos·动态规划·cangjie
我狠狠地刷刷刷刷刷15 分钟前
中文分词模拟器
开发语言·python·算法
鸽鸽程序猿16 分钟前
【算法】【优选算法】前缀和(上)
java·算法·前缀和
九圣残炎22 分钟前
【从零开始的LeetCode-算法】2559. 统计范围内的元音字符串数
java·算法·leetcode
YSRM34 分钟前
Experimental Analysis of Dedicated GPU in Virtual Framework using vGPU 论文分析
算法·gpu算力·vgpu·pci直通
幸运小圣1 小时前
Vue3 -- 项目配置之stylelint【企业级项目配置保姆级教程3】
开发语言·后端·rust
韭菜盖饭1 小时前
LeetCode每日一题3261---统计满足 K 约束的子字符串数量 II
数据结构·算法·leetcode
geng小球1 小时前
LeetCode 78-子集Ⅱ
java·算法·leetcode
AnFany1 小时前
LeetCode【0028】找出字符串中第一个匹配项的下标
python·算法·leetcode·字符串·kmp·字符串匹配
无敌最俊朗@1 小时前
stm32学习之路——八种GPIO口工作模式
c语言·stm32·单片机·学习