Rust - 基础语法

文章目录

    • 注释
    • 基本输出
      • 输出 `{}`
    • 变量
      • 重影(Shadowing)
    • 数据类型
      • 整数型(Integer)
      • 浮点数型(Floating-Point) f32、f64
      • 数学计算
      • 布尔型 bool
      • 字符型 char
      • 元组 ()
      • 数组 []
      • .. 表示范围
      • 切片 slice
      • 结构体
      • 枚举
        • match 处理分支
        • Option 枚举类
      • 集合
      • 向量
      • 字符串
      • 映射表 Map
    • 函数
      • 函数体表达式
    • 条件语句
      • if
    • 循环
      • while
      • for-in
      • loop


本文转载改编自:https://www.runoob.com/rust/rust-tutorial.html


注释

// 这是第一种注释方式/* 这是第二种注释方式 *//** 多行注释* 多行注释* 多行注释*//// 说明文档的注释

基本输出

Rust 中格式字符串中的占位符不是 “% + 字母” 的形式,而是一对 {}

println!("a is {0}, a again is {0}", a); 

{} 之间可以放一个数字,它将把之后的可变参数当作一个数组来访问,下标从 0 开始。

println!("a is {}", a);

输出 {}

{{}}

其他常用转义字符与 C 语言里的转义字符一样,都是反斜杠开头的形式。

println!("{{}}"); 

变量

Rust 是强类型语言,但可以自动判断变量类型。

声明变量,使用 let 关键字。

// 声明为 不可变变量,被判断为有符号 32 位整型变量
let a = 123;  
let a = 456; // 变量未被使用,会有警告 但不报错
// a = "abc";  // 非法,
// a = 4.56;  // 非法,// 可变
let mut b = 123;
b = 456;// 申明为常量
const a: i32 = 123;
let a = 456;


重影(Shadowing)


重影:重新绑定,指变量的名称 可以被 重新使用的机制

重影与 可变变量的赋值 不是一个概念,重影是指 用同一个名字 重新代表 另一个变量实体,其类型、可变属性和值都可以变化。但可变变量赋值仅能发生值的变化。

let x = 5;
let x = x + 1;
let x = x * 2;
println!("The value of x is: {}", x); // 12 let mut s = "123";
// s = s.len();  // 会出错:不能给字符串变量赋整型值

数据类型


整数型(Integer)

整数型简称 整型,按照 比特位长度 和 有无符号 分为以下种类:

位长度有符号无符号
8-biti8u8
16-biti16u16
32-biti32u32
64-biti64u64
128-biti128u128
archisizeusize

isize 和 usize 两种整数类型是用来衡量数据大小的,它们的位长度取决于所运行的目标平台,如果是 32 位架构的处理器将使用 32 位位长度整型。


整数的表述方法有以下几种:

进制
十进制98_222
十六进制0xff
八进制0o77
二进制0b1111_0000
字节(只能表示 u8 型)b’A’

很显然,有的整数中间存在一个下划线,这种设计可以让人们在 输入一个很大的数字时,更容易判断数字的值大概是多少。


浮点数型(Floating-Point) f32、f64

Rust 与其它语言一样支持 32 位浮点数(f32)和 64 位浮点数(f64)。

默认情况下,64.0 将表示 64 位浮点数,因为现代计算机处理器对两种浮点数计算的速度几乎相同,但 64 位浮点数精度更高。

let x = 2.0; // f64
let y: f32 = 3.0; // f32

数学计算

let sum = 5 + 10; // 加
let difference = 95.5 - 4.3; // 减
let product = 4 * 30; // 乘
let quotient = 56.7 / 32.2; // 除
let remainder = 43 % 5; // 求余// 自运算
sum += 1 // 等同于 sum = sum + 1

Rust 不支持 ++--


布尔型 bool

布尔型用 bool 表示,值只能为 true 或 false。


字符型 char

用 char 表示,大小为 4 个字节,代表 Unicode标量值,这意味着它可以支持中文,日文和韩文字符等非英文字符,甚至 表情符号 和 零宽度空格 在 Rust 中都是有效的 char 值。

Unicode 值的范围从 U+0000 到 U+D7FF 和 U+E000 到 U+10FFFF (包括两端)。 但是,"字符"这个概念并不存在于 Unicode 中,因此您对"字符"是什么的直觉可能与Rust中的字符概念不匹配。所以一般推荐使用字符串储存 UTF-8 文字(非英文字符尽可能地出现在字符串中)。

**注意:**由于中文文字编码有两种(GBK 和 UTF-8),所以编程中使用中文字符串有可能导致乱码的出现,这是因为源程序与命令行的文字编码不一致,所以在 Rust 中字符串和字符都必须使用 UTF-8 编码,否则编译器会报错。



元组 ()

用一对 ( ) 包括的一组数据,可以包含不同种类的数据:

let tup: (i32, f64, u8) = (500, 6.4, 1);
// tup.0 等于 500
// tup.1 等于 6.4
// tup.2 等于 1let (x, y, z) = tup; // y 等于 6.4

数组 []

// a 是一个长度为 5 的整型数组
let a = [1, 2, 3, 4, 5]; // b 是一个长度为 3 的字符串数组
let b = ["January", "February", "March"]; // c 是一个长度为 5 的 i32 数组
let c: [i32; 5] = [1, 2, 3, 4, 5];let d = [3; 5]; // 等同于 let d = [3, 3, 3, 3, 3];// 数组访问
let first = a[0];
let second = a[1];a[0] = 123; // 错误:数组 a 不可变let mut a = [1, 2, 3];
a[0] = 4; // 正确

… 表示范围

  • ..y 等价于 0..y
  • x.. 等价于位置 x 到数据结束
  • .. 等价于位置 0 到结束
  • x..y 表示 [x, y)

切片 slice

// 字符串切片 
let s = String::from("broadcast");let part1 = &s[0..5];
let part2 = &s[5..9];println!("{}={}+{}", s, part1, part2); // broadcast=broad+castlet arr = [1, 3, 5, 7, 9];
let part = &arr[0..3];
for i in part.iter() {println!("{}", i);
}
  • str 是 Rust 核心语言类型,就是这里的 字符串切片(String Slice),常常以引用的形式出现(&str)。
  • 用双引号包括的字符串常量整体的类型性质都是 &strlet s = "hello";
  • 切片结果必须是引用类型,但开发者必须自己明示这一点
  • String 转换成 &str
let s1 = String::from("hello");
let s2 = &s1[..]; 

结构体

  • Rust 里 struct 语句仅用来定义,不能声明实例;
  • 结尾不需要 ; 符号 ,且每个字段定义之后用 , 分隔
// 定义
struct Site {domain: String,name: String,nation: String,found: u32
}// 实例化 - 用 JSON 对象的 key: value 语法
let runoob = Site {domain: String::from("www.runoob.com"),  // 字段名 : 字段值,  name: String::from("RUNOOB"),nation: String::from("China"),found: 2013
};// 简化 - 现存变量名称 和 结构体字段名称 一样 
let domain = String::from("www.runoob.com");
let name = String::from("RUNOOB");
let runoob2 = Site {domain,  // 等同于 domain : domain,name,    // 等同于 name : name,nation: String::from("China"),traffic: 2013
};// 现有结构体基础上,新建结构体;不能一成不变 
let site = Site {domain: String::from("www.runoob.com"),name: String::from("RUNOOB"),..runoob  // 后面不可以有逗号 
};// 元组结构体 - 有名字和固定的类型格式,简单数据
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);  // black = (0, 0, 0)
println!("origin = ({}, {})", origin.0, origin.1);  // origin = (0, 0)

枚举

enum Book {Papery, Electronic
}let book = Book::Papery;
println!("{:?}", book);// 描述属性
enum Book2 {Papery(u32),Electronic(String),
}let book = Book2::Papery(1001);
let ebook = Book2::Electronic(String::from("url://..."));// 为属性命名 - 可以用结构体语法
enum Book3 {Papery { index: u32 },Electronic { url: String },
}
let book = Book3::Papery{index: 1001};

match 处理分支
let book = Book3::Papery{index: 1001};
match book {Book::Papery { index } => {println!("Papery book {}", index);},Book::Electronic { url } => {println!("E-book {}", url);}
}
// -> Papery book 1001match book {Book::Papery(i) => {   // 分类1 => 返回值表达式,println!("{}", i);},Book::Electronic { url } => {println!("{}", url);}
}let t = "abc";
match t {"abc" => println!("Yes"),_ => {},
}

Option 枚举类
enum Option<T> {Some(T),None,
}// 定义一个可以为空值的类
let opt = Option::Some("Hello");// 对 opt 执行某些操作,必须先判断它是否是 Option::None:
let opt = Option::Some("Hello");
match opt {Option::Some(something) => {println!("{}", something);},Option::None => {println!("opt is nothing");}
}

集合


向量

表示:Vec<T> ,使用方式类似于列表(List)

let vector: Vec<i32> = Vec::new(); // 创建类型为 i32 的空向量
let vector = vec![1, 2, 4, 8];     // 通过数组创建向量// 追加单个元素
vector.push(16);
vector.push(32);
vector.push(64);
println!("{:?}", vector);  // [1, 2, 4, 8, 16, 32, 64]// append 拼接两个向量
let mut v1: Vec<i32> = vec![1, 2, 4, 8];
let mut v2: Vec<i32> = vec![16, 32, 64];
v1.append(&mut v2);
println!("{:?}", v1);  // [1, 2, 4, 8, 16, 32, 64]// get 取值 - 向量的长度无法从逻辑上推断,get 无法保证一定取到值,返回值是 Option 枚举类,有可能为空。
println!("{}", match v1.get(0) {Some(value) => value.to_string(),None => "None".to_string()
});
// -> 1println!("{}", v[1]); // 2// 遍历
for i in &v {println!("{}", i);
}// 遍历中修改 
let mut v = vec![100, 32, 57];
for i in &mut v {*i += 50;
}

字符串

// 新建
let string = String::new();// 基础类型转换成字符串:
let one = 1.to_string();         // 整数到字符串
let float = 1.3.to_string();     // 浮点数到字符串
let slice = "slice".to_string(); // 字符串切片到字符串// 包含 UTF-8 字符的字符串:
let hello = String::from("שָׁלוֹם");
let hello = String::from("नमस्ते");// 追加
let mut s = String::from("run");
s.push_str("oob"); // 追加字符串切片
s.push('!');       // 追加字符// + 拼接字符串:
let s1 = String::from("Hello, ");
let s2 = String::from("world!");
let s3 = s1 + &s2;// 这个语法也可以包含字符串切片:
let s1 = String::from("tic");
let s2 = String::from("tac");
let s3 = String::from("toe");let s = s1 + "-" + &s2 + "-" + &s3;// 使用 format! 宏:
let s1 = String::from("tic");
let s2 = String::from("tac");
let s3 = String::from("toe");let s = format!("{}-{}-{}", s1, s2, s3);// 字符串长度:
let s = "hello";
let len = s.len(); // 5let s = "你好";
let len = s.len(); // 6 - UTF-8 编码的,每个字符长 3 字节let s = "hello你好";  
let len = s.chars().count(); // 7 - 获得 字符集合 // 获取单个字符
let s = String::from("EN中文");
let a = s.chars().nth(2);  // nth 从迭代器中取出某值;不要在遍历中这样使用,因为 UTF-8 每个字符的长度不一定相等
println!("{:?}", a);   // Some('中') let sub = &s[0..2];
println!("{}", sub);  // ENlet sub = &s[0..3]; // 报错 - 肢解了字符串

映射表 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());  // red  // 遍历for p in map.iter() {println!("{:?}", p);  // ("color", "red") }// 安全插入,不覆盖原来的值;如有 就跳过。map.entry("color").or_insert("red");// 更快map.insert(1, "a");if let Some(x) = map.get_mut(&1) {*x = "b";}
}

函数

语法:

fn <函数名> ( <参数> ) <函数体>


  • 函数名称的命名风格:小写字母 以 下划线分割
  • 不在乎 在哪里 定义函数
fn main() {println!("Hello, world!");another_function();another_function2(5, 6);let a = add(15, 8); 
}fn another_function() {println!("Hello, runoob!");
}// 声明参数名称和类型
fn another_function2(x: i32, y: i32) {println!("x 的值为 : {}", x);println!("y 的值为 : {}", y);
}// 有返回值
fn add(a: i32, b: i32) -> i32 {return a + b;
}

函数体表达式

Rust 中可以在一个用 {} 包括的块里 编写一个较为复杂的表达式:

fn main() {let x = 5;let y = {let x = 3;x + 1   // 最后一个步骤 的这个表达式,它的结果值,是 整个表达快 代表的值;注:没有分号,否则它将变成一条语句。};println!("x 的值为 : {}", x);  // 5println!("y 的值为 : {}", y);  // 4
}

函数定义可以嵌套:

fn main() {fn five() -> i32 {5}println!("five() 的值为: {}", five());
}

条件语句


if

let number = 3;
if number < 5 {println!("条件为 true");
} else {println!("条件为 false");
}// else if
let a = 12; 
let b; 
if a > 0 { b = 1; 
} else if a < 0 { b = -1; 
} else { b = 0; 
}
println!("b is {}", b); // 1// 三元
let a = 3;
let number = if a > 0 { 1 } else { -1 }; // 1
  • 条件表达式 number < 5 不需要用小括号包括(注意,并非不允许)
  • 条件表达式必须是 bool 类型。如 if 1 非法。

循环


while

let mut number = 1;
while number != 4 {println!("{}", number);number += 1;
}
println!("EXIT");let mut i = 0;
while i < 10 {// 循环体i += 1;
}
  • 目前没有 do-while , for-i

for-in

let a = [10, 20, 30, 40, 50];
for i in a.iter() {println!("值为 : {}", i);
}for i in 0..5 {println!("a[{}] = {}", i, a[i]);
}

loop

类似于 while (true)

let s = ['R', 'U', 'N', 'O', 'O', 'B']; 
let mut i = 0; loop { let ch = s[i]; if ch == 'O' { break; } println!("\'{}\'", ch);i += 1; 
} // 当作查找工具,将结果交出去
let location = loop { let ch = s[i];if ch == 'O' { break i; } i += 1; 
}; 
println!(" \'O\' 的索引为 {}", location);  // 3

伊织 2024-05-08(三)
https://music.163.com/#/song?id=2072541999

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/9964.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

AI大模型探索之路-训练篇20:大语言模型预训练-常见微调技术对比

系列篇章&#x1f4a5; AI大模型探索之路-训练篇1&#xff1a;大语言模型微调基础认知 AI大模型探索之路-训练篇2&#xff1a;大语言模型预训练基础认知 AI大模型探索之路-训练篇3&#xff1a;大语言模型全景解读 AI大模型探索之路-训练篇4&#xff1a;大语言模型训练数据集概…

nginx 详解

Nginx&#xff08;发音为“Engine-X”&#xff09;是一个高性能的HTTP和反向代理服务器&#xff0c;也是一个IMAP/POP3代理服务器。Nginx以其高稳定性、丰富的功能集、简单的配置和低资源消耗而闻名。它特别适用于处理高并发请求&#xff0c;这部分归功于其事件驱动和异步架构。…

RF Plasma gernerator-系列(RF-5KW Adtec)说明书TX06-9001-00

RF Plasma gernerator-系列(RF-5KW Adtec)说明书TX06-9001-00

深度学习课程论文精读——ESRGAN

目录 1.研究概述 2.论文创新 2.1 改进生成器的网络框架 2.2 改进判别器 2.3 改进感知损失 2.4 网络插值 3.实验 3.1 评价指标 3.2 训练细节 3.3 对比实验 3.4 消融实验 3.5 网络插值 4.总结 5.阅读参考 文章标题&#xff1a;《ESRGAN: Enhanced Super-Resolution…

Hive优化(1)——分桶采样

分桶&#xff08;Bucketing&#xff09; 分桶是将数据按照某个字段的哈希值进行分组存储的一种技术。它的原理是将数据按照指定字段的哈希值分成固定数量的桶&#xff0c;将每条记录分配到对应的桶中。分桶可以帮助优化特定类型的查询&#xff0c;例如连接查询和聚合操作&…

2024OD机试卷-攀登者1 (java\python\c++)

题目:攀登者1 题目描述 攀登者喜欢寻找各种地图,并且尝试攀登到最高的山峰。 地图表示为一维数组,数组的索引代表水平位置,数组的元素代表相对海拔高度。其中数组元素0代表地面。 例如:[0,1,2,4,3,1,0,0,1,2,3,1,2,1,0],代表如下图所示的地图,地图中有两个山脉位置分别…

TS-声明文件

目录 1&#xff0c;什么是声明文件2&#xff0c;作用3&#xff0c;位置1&#xff0c;tsconfig.json 配置的包含目录中2&#xff0c;node_modules/types 目录中3&#xff0c;typeRoots 配置项中的目录4&#xff0c;与 js 文件同名同目录的文件 4&#xff0c;编写1&#xff0c;ts…

java中List的toArray()方法

toArray()介绍 toArray()方法是List接口中提供的方法&#xff0c;用来实现List对象转换为数组对象的功能。 toArray()方法有两种形式&#xff0c;无参方法和带泛型的方法&#xff0c;接下来给出例子。 1.toArray() // toArray()源码public Object[] toArray() {return Arrays.…

携手鲲鹏昇腾 HashData展现云原生数仓创新力量

​5月9日-11日&#xff0c;鲲鹏昇腾开发者大会2024在北京中关村国际创新中心举行&#xff0c;众多行业领袖、专家学者及优秀开发们齐聚一堂&#xff0c;分享产业趋势、技术创新和应用实践。 酷克数据作为华为鲲鹏生态重要合作伙伴&#xff0c;受邀出席本次大会&#xff0c;展示…

C++ Primer Plus 知识的讲解

程序模板 #pragma region xxx.cpp //xxx.cpp -- xxx #if 0 #include <iostream> int main() {using namespace std;return 0; } #endif #pragma endregionC Primer Plus 知识的讲解 第一章&#xff1a;预备知识 本章内容包括&#xff1a; .C语言和C的发展历史和基本原…

大语言模型LLM原理篇

大模型席卷全球&#xff0c;彷佛得模型者得天下。对于IT行业来说&#xff0c;以后可能没有各种软件了&#xff0c;只有各种各样的智体&#xff08;Agent&#xff09;调用各种各样的API。在这种大势下&#xff0c;笔者也阅读了很多大模型相关的资料&#xff0c;和很多新手一样&a…

sass 详解

Sass&#xff08;Syntactically Awesome Style Sheets 的缩写&#xff09;是一种 CSS 预处理器&#xff0c;用于使CSS的使用更加高效和动态。它允许使用变量、嵌套规则、混合和函数等功能&#xff0c;以编写更可维护、更强大的代码。Sass 主要有两种语法格式&#xff1a;SCSS&a…

【Redis】用户登录校验

对于用 redis 对用户进行登录校验&#xff0c;大致可分为以下六步&#xff1a; 首先通过查询数据库来查找具有提供的用户名、密码和delFlag值为0的用户。如果未找到用户&#xff0c;则抛出一个带有消息"用户不存在"的ClientException&#xff08;用户不存在&#xf…

【产品应用】一体化伺服电机在拉力系统设备中的应用

随着工业自动化的快速发展&#xff0c;高精度、高效率的传动与控制设备需求日益增长。一体化伺服电机作为一种集驱动、控制、反馈于一体的智能型电机&#xff0c;因其卓越的性能&#xff0c;在各类工业设备中得到了广泛应用。特别是在拉力实验设备中&#xff0c;一体化伺服电机…

WebRTC 的核心:RTCPeerConnection

WebRTC 的核心&#xff1a;RTCPeerConnection WebRTC 的核心&#xff1a;RTCPeerConnection创建 RTCPeerConnection 对象RTCPeerConnection 与本地音视频数据绑定媒体协商ICE什么是 Candidate&#xff1f;收集 Candidate交换 Candidate尝试连接 SDP 与 Candidate 消息的互换远端…

线程同步--互斥锁,读写锁

线程同步 基本概念 线程的能力在于能够方便地通过全局变量或共享内存来交换信息&#xff0c;但这也带来了并发控制的复杂性&#xff0c;主要表现在如何安全地管理多个线程对共享资源的访问。这里涉及到几个关键的概念和技术&#xff1a; 临界区&#xff08;Critical Section…

jenkins部署想定报错

报错&#xff1a; 解决办法&#xff1a; 登录被编译的设备&#xff0c;清楚旧代码&#xff0c;在重新执行

Dependencies:查找项目中dll关联文件是否缺失。

前言 Dependencies工具作为一款优秀的DLL解析工具&#xff0c;能让你很直观地看到DLL的相关信息&#xff0c;如具备哪些功能函数、参数&#xff0c;又比如该DLL基于哪些DLL运行。判断该dll基于哪些dll运行&#xff0c;如果基于的dll丢失&#xff0c;那么就会提示。就能判断缺少…

【Ubuntu永久授权串口设备读取权限‘/dev/ttyUSB0‘】

Ubuntu永久授权串口设备读取权限 1 问题描述2 解决方案2.1 查看ttyUSB0权限&#xff0c;拥有者是root&#xff0c;所属用户组为dialout2.2 查看dialout用户组成员&#xff0c;如图所示&#xff0c;普通用户y不在dialout组中2.3 将普通用户y加入dialout组中2.4 再次查看dialout用…

知识付费系统规格表,添加家长微信后需要做什么?怎么维护?

一般来说&#xff0c;在认识家长的时候&#xff0c;都会加家长微信好友&#xff0c;这是为了能利用微信这个平台&#xff0c;达到更好做业绩的效果&#xff0c;教育机构一定要学会利用微信维护好与家长关系&#xff0c;从而吸引更多家长&#xff0c;添加家长微信后需要做什么?…