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 等于 1

let (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+cast

let 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 1001

match 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()
});
// -> 1

println!("{}", 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(); // 5

let 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);  // EN

let 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);  // 5
    println!("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.mfbz.cn/a/605325.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

MacOS miniconda安装方法

打开macos “终端” 应用 执行命令 mkdir -p ~/miniconda3curl https://mirrors.tuna.tsinghua.edu.cn/anaconda/miniconda/Miniconda3-latest-MacOSX-arm64.sh -o ~/miniconda3/miniconda.shbash ~/miniconda3/miniconda.sh -b -u -p ~/miniconda3rm -rf ~/miniconda3/mini…

CPU基本知识点

目录 1.概念 2.分类 3.运作原理 4.指令系统 1.概念 CPU&#xff1a;英文Central Processing Unit&#xff0c;即中央处理器。 解释和执行指令的功能单元&#xff0c;它是计算机的中枢神经系统&#xff08;即核心&#xff09;。 是计算机最核心的部件&#xff0c;主要是运算…

嵌入式数据库SQLite 3配置使用详细笔记教程

0、惨痛教训 随着管理开发的项目体积越来越庞大&#xff0c;产品系统涉及的数据量也越来越多&#xff0c;并且伴随着项目不久就要交付给甲方了。如果项目的数据信息没有被妥善管理&#xff0c;后期设备的运行状态、操作状况等数据流信息不能被溯源&#xff0c;当出现了一些特殊…

【35分钟掌握金融风控策略16】贷前风控策略详解-1

目录 贷前风控策略详解 贷前风控目标 精准审核申请贷款客户资质 对申请贷款客户进行合理定额 对申请贷款客户进行合理定价 推动实现利润最大化 贷前风控数据源 客户贷款时提供的数据 贷前风控策略详解 俗话说&#xff0c;良好的开端是成功的一半&#xff0c;而贷前是风…

C++新手村指南:入门基础

目录 C概念 C发展史 C关键字&#xff08;C98&#xff09; 命名空间 命名空间的定义 命名空间的使用 C中的输入&&输出 缺省参数 缺省参数的概念 缺省参数的分类 函数重载 函数重载概念 函数重载实现 引用 引用的概念 引用的特性 常引用 引用的使用场景…

基于单片机的小型自动浇灌系统设计

摘 要:以单片机为主控芯片,结合传感器和计算机,搭建了一套智能化的浇灌系统;利用LabVIEW 设计并编写了基于状态机程序架构的上位机软件,实现了友好的用户交互界面,实时测量、显示与记录等功能,并由主控芯片进行浇灌。经测试,本系统具有结构简单,研制成本低,运…

详细介绍一下PointPillars算法的网络结构

PointPillars是一种用于3D目标检测的算法&#xff0c;它主要使用了点云数据和深度学习模型。 PointPillars算法的网络结构主要可以分为三个主要阶段&#xff1a; Pillar Feature Net&#xff08;点云特征处理网络&#xff09;&#xff1a;此阶段的主要任务是将输入的点云数据转…

回答篇:测试开发高频面试题目

引用之前文章&#xff1a;《测试开发高频面试题目》 https://blog.csdn.net/qq_41214208/article/details/138193469?spm1001.2014.3001.5502 本篇文章是回答篇&#xff08;持续更新中&#xff09; 1. 什么是测试开发以及其在软件开发流程中的作用。 a. 测试开发是指测试人员或…

Java:Servlet详解

目录 一、什么是Servlet 二、Servlet原理 Servlet的生命周期 三、 Servlet注释 WebServlet 一、什么是Servlet Servlet是JavaWeb开发的一种技术&#xff0c;Servlet程序需要部署在Servlet容器&#xff08;服务端&#xff09;中才能运行&#xff0c;常见的Servlet容器有Tom…

【C++】环境搭建CentOS Clion报错Unsupported git Version 1.8.3.1

【C】环境搭建Clion-Unsupported git Version 1.8.3.1 Git升级步骤1.卸载旧版本2.安装依赖3.下载git最新版本包4.解压git文件包5.编译文件5.将git加入环境变量6.验证git版本 如上图所示&#xff0c;报错Unsupported git Version 1.8.3.1 At least 2.17.0 is required 报错意思…

windows驱动开发-inf文件(一)

驱动总是和inf文件相关&#xff0c;在WinDDK的时候&#xff0c;许多inf文件都需要开发工程师手动编写&#xff0c;不过&#xff0c;现在已经可以使用inx文件来生成inf文件了&#xff0c;它经常用于驱动的安装和卸载&#xff1b;不过&#xff0c;并不是所有的驱动都需要使用inf文…

小白修复msvcp140.dll丢失的解决方法,一键修复丢失的dll文件

在我们使用电脑时&#xff0c;常常会碰到各种烦人的状况。比方说&#xff0c;当我们期待畅玩游戏时&#xff0c;可能会突然遭遇一则令人沮丧的提示&#xff1a;“打开游戏缺少msvcp140.dll文件”。这个问题会给我们带来困扰和不愉快&#xff0c;但庆幸的是&#xff0c;有多种解…

UE4_Water插件_Buoyancy组件使用

water插件提供了一个浮力Actor蓝图类。 需要注意的几个问题&#xff1a; 1、StaticMesh需要替换根组件。 2、需要模拟物理设置质量。 3、需要添加浮力组件&#xff0c;设置浮力点&#xff0c;应用水中牵引力。 4、最重要的是需要激活——自动启用。 5、调水波长的地方 双击图片…

【JavaScript】内置对象 - Date 日期对象 ④ ( 制作倒计时页面 )

文章目录 一、倒计时页面实现1、需求分析2、计算秒数3、计算倒计时时间的 天 / 时 / 分 / 秒4、页面中显示倒计时时间 二、完整代码示例1、完整代码2、执行结果 Date 日期对象参考文档 : https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Da…

北京大学肖臻老师《区块链技术与应用》P16(状态树)和P17(交易树和收据树)

1️⃣ 参考 北京大学肖臻老师《区块链技术与应用》 P16 - ETH状态树篇P17 - ETH交易树和收据树篇 部分文字和图片 北京大学肖臻老师《区块链技术与应用》公开课笔记18——ETH数据结构篇2(状态树2)北京大学肖臻老师《区块链技术与应用》公开课笔记19——ETH数据结构篇3(交易树和…

入门视频剪辑:视频合并不再难,批量嵌套合并的简单步骤

在数字媒体时代&#xff0c;视频剪辑已成为一项基本技能。无论是制作家庭电影、公司宣传片还是在线教育内容&#xff0c;视频剪辑都扮演着重要角色。对于初学者来说&#xff0c;视频剪辑可能看起来有些复杂&#xff0c;但掌握了正确的步骤和技巧后&#xff0c;你会发现它其实并…

Angular中的路由

Angular中的路由 文章目录 Angular中的路由前言一、创建路由二、创建多个组件路由三、创建子路由四、创建多个组件子路由 前言 在Angular中&#xff0c;路由是用于在不同的视图和组件之间导航的机制。Angular提供了一种强大的路由机制来管理单页应用&#xff08;SPA&#xff0…

十九、分布式数据库MyCat

目录 一、概述 1、MyCat是什么&#xff1f; 2、原理&#xff1a; 3、能干什么 1、读写分离 2、数据分片 3、多数据源整合 4、Mycat监控 4、安装部署 1、环境准备 2、安装 3、Mycat配置详解 1、server.xml user 标签 2、schema.xml schema标签&#xff1a; table标签&…

实践遥感卫星场景海洋船只检测,基于YOLOv8全系列【n/s/m/l/x】参数模型开发构建卫星遥感场景下海洋海面船只检测识别系统

遥感相关的实践在我们前面的系列博文中也有相关的一些实践&#xff0c;胡药师基于MASTAR数据集开发构建对应的目标检测系统在前文也有一些介绍&#xff0c;感兴趣的话可以自行移步阅读即可&#xff1a; 《基于YOLOv7开发构建MSTAR雷达影像目标检测系统》 《基于yolov5n的轻量…

多角度解析动态住宅IP的多元化应用

动态住宅IP指的是在住宅网络中使用的、能够随时间或用户需求配置的IP地址&#xff0c;能够根据网络状况自动调整&#xff0c;为用户提供更加灵活、高效的上网体验。这种IP地址不是固定不变的&#xff0c;而是会定期自动更换&#xff0c;这种IP地址也让使用者的安全得以保障。 作…
最新文章