rust中使用let关键字来初始化一个变量,变量在初始化的时候必须有一个初始值,同时rust中变量不可变,在初始化之后就不可以再更改了:
//变量不可变
let x = 5;
//这种情况是不允许的,不可以二次赋值
x = 6;
使用mut关键字可以使得变量成为可以改变的:
//变量不可变
let mut x = 5;
//这种情况是允许的,mut变量二次赋值
x = 6;
使用const关键字可以定义常量,常量不可以mut,并且必须声明类型,可以在全局定义,全大写。常量可以在任何作用域中声明,比如main函数之前:
const X:i32 = 1000;
如果我们先声明一个变量,之后再用let声明同一个变量,这是允许的,我们称之为第一个变量隐藏了,这一个过程中,变量的类型和数值都可以改变,这一个操作的好处是节约内存:
//shadow
let x = 5;
let x = true;
Rust 是静态类型语言,也就是说在编译时就必须知道所有变量的类型
rust的整数分为有符号和无符号两种,同时我们可以通过设定长度来限制整数的长度,长度可以设置为8,16,32,64,128这几种,同时rust还支持使用isize这样的形式定义整数,它可以根据本机的位数来设定长度,比如64位的电脑就与i64的效果一致。可以使用下面两种方式来定义一个指定类型的整数
let num:u8 = 42;
let num = 42u8;
同时我们可以使用多种进制来表述一个整数类型值
//十进制,可以使用_隔开,与98222一致
let num = 98_222;
//十六进制
let num = 0xff;
//八进制
let num = 0o77;
//二进制
let num = 0b1111;
//单字节字符(仅限u8)
let num = b'A';
浮点数仅有32和64位两种类型,默认类型是 64位浮点数
//这个时候就算f64
let x = 2.0;
let y:f32 = 2.0;
Rust 中的所有数字类型都支持基本数学运算:加法、减法、乘法、除法和取余,分别使用 +,-,*,/,%符号来完成,除法会向下取最接近的整数。
Rust 中的布尔类型(bool)有两个可能的值:true和 false
//boolean
let t:bool = true;
rust中的字符类型数据占4给字节,并且使用 Unicode 编码,所以我们可以使用英文字母,外文字母,emjoy表情等字符:
let c = 'z';
let z: char = 'ℤ';
let heart_eyed_cat = '😻';
复合类型将多个值组合成一个类型,Rust 有两个原生的复合类型:元组(tuple)和数组(array)
元组tuple,长度固定,且内容不能修改,元组中的数据类型可以不同
let tup = (10,21,'c');
使用模板匹配的方式可以提取出元组的每一个数据,也可以通过下标来访问
let (x,y,z) = tup;
let k = tup.1;
不带任何值的元组有个特殊的名称,叫做单元(unit) 元组。这种值以及对应的类型都写作 (),表示空值或空的返回类型。如果表达式不返回任何其他值,则会隐式返回单元值。
数组array同样长度固定,但是其中的类型必须一致,内容也同样不可变:
let arr = [1,2,3,4];
//使用[类型;数量]的方式可以定义数组的类型
//同时如下方式可以直接生成[3,3,3,3,3]5个3的数组
let a:[i32;5]= [3;5];
数组可以通过下标访问
let first = a[0];
fn关键字,它用来声明新函数,函数中的参数必须声明类型,如果函数有返回值,返回的内容也必须给出类型,函数的定义如下:
//函数定义,参数类型必须指明,返回值也需要声明
fn test(x:i32,y:i32) -> i32 {
5
}
函数中的执行某些操作的指令被称为语句,语句由分号结尾;二返回一个值的指令被曾为表达式,表达式不能由分号结尾,一个函数可以包括多个语句,同时在函数结尾需要一个表达式来作为函数的返回值。
//函数定义,参数类型必须指明,返回值也需要声明
fn test(x:i32,y:i32) -> i32 {
//语句
let x = x+1;
let y = y+1;
//表达式
x+y
}
rust和其他语言类似具有if等条件控制语句,也有while和for等循环语句
if 表达式允许根据条件执行不同的代码分支。if 语句中包含一个表达式,表达式的值必须是一个bool类型,返回true或者false,要注意,rust并不会将其他类型的值转化为bool进行运算,if(1)这些的写法是不允许的:
if number > 5 {
println!("1");
}else if number == 5 {
println!("2");
}else{
println!("3");
}
//这样是不允许的:
if number {
}
可以通过在 if 语句中返回一个表达式来实现“三目运算” 等类似操作,但是返回值必须是同一个类型
let condition = true;
//相当于三目运算,但是返回值必须一致
let num = if condition {5} else {6};
loop 循环将循环执行它包含的语句,直到遇到 break 关键字将其中断,同时在break之后还可以编写一个表达式作为返回值。要注意,此处需要一个分号,因为整个语句是一个赋值语句。
let mut conuter = 1;
let re = loop {
conuter += 1;
if conuter == 10 {
//返回,并且可以返回值
break conuter * 2;
}
};
//整个相当于一个 let re = 10 * 2; 这样的语句
如果有多重循环,可以通过给定一个循环标签的方式来告知中断哪一个循环
fn main() {
let mut count = 0;
//给定一个标签
'counting_up: loop {
println!("count = {count}");
let mut remaining = 10;
loop {
println!("remaining = {remaining}");
if remaining == 9 {
break;
}
if count == 2 {
//中断指定标签的循环
break 'counting_up;
}
remaining -= 1;
}
count += 1;
}
println!("End count = {count}");
}
while 循环在指定的条件为真时循环执行
while conuter != 0 {
conuter = conuter -1;
}
for 循环可以限定循环的次数,你可以用 for 语句遍历一个数组中的每一个元素,也可以使用range自己创建一个循环的范围来限定循环次数,使用range创建的范围是 [ a,b ) 的区间,可以取到初值但是不能取到末值
let a = [10, 20, 30, 40, 50];
for e in a {
println!("{}",e);
}
//在一个范围内运行,不包含10,包含1
for e in (1..10) {
println!("{}",e);
}
rust使用struct来定义一个包含多种数据类型的结构,struct 中的每个字段需要给出名字和数据类型,在创建一个struct 实例时,需要对其中的每一个字段赋值,同样,struct 实例也可以是可变的,如果一个 struct 实例是可变的,那么其中的每一个字段都是可变的,使用 . 记号可以找到实例中的字段
struct User {
name:String,
email:String,
active:u32,
}
//实例化
let mut user1 = User{
email:String::from("122"),
name:String::from("zs"),
active:1,
};
//修改一个值
user1.email = String::from("121212");
//如果给与一个字段的值和他的名称一致,可以省略不写,如下:
let email = String::from("122");
let mut user2 = User{
email,
name:String::from("zs"),
active:1,
};
使用扩展运算符 .. 可以将一个struct 实例展开,展开的 struct 可以用于填出其他的 struct 实例
let mut user2 = User{
..user1
};
rust 还支持元组 struct 这样的 struct ,他的定义类似于元组,字段不需要名称,字段的获取方式也和元组类似
//tuple struct,变量没名字
struct Color(i32,i32,i32);
let black = Color(0,0,0);
使用 impl 块可以为 struct 创建方法,需要传入一个 &self 代表本身,传入这个参数之后,可以调用 struct 中的字段元素,在 self 之后可以传入其他元素,将 struct 实例化之后,使用 . 来调用对应的方法,要注意,调用方法时,并不需要传入 &self 这个参数
struct Long{
a:u32,
b:u32,
};
//impl块用于定义方法
impl Long {
fn greater(&self, other: &Long) -> u32 {
if self.a > other.a {
1
}else{
2
}
}
};
println!("{}",l1.greater(&l2))
如果函数中不包含 &self 这个参数,那么这个函数不需要实例化也可以调用,调用方式也是使用 :: 来调用,类似我们之前使用的在String中的 String::from ,这类函数常用于初始化一个 struct 实例,类似于其他语言中的 new
impl Long {
fn creat_long(a: u32) -> Self {
Self {
a: a,
b: a,
}
}
}
let l3 = Long:: creat_long (1);
枚举类型允许你给出所有的可能值作为成员创建一种新的数据类型,使用 :: 可以创建一个枚举中一种类型的实例。当你使用 IpAddrKind 作为变量类型时,IpAddrKind::V4 和IpAddrKind::V6 都可以与其匹配
enum IpAddrKind {
V4,
V6,
}
let four = IpAddrKind::V4;
let six = IpAddrKind::V6;
//route(IpAddrKind::V4) 和 route(IpAddrKind::V6) 都可以传入
fn route(ip_kind: IpAddrKind) {}
在rust中,我们可以直接将数据附加到枚举的每个成员上,这里直接展示一个例子来说明:
enum IpAddr {
V4(u8, u8, u8, u8),
V6(String),
}
let home = IpAddr::V4(127, 0, 0, 1);
let loopback = IpAddr::V6(String::from("::1"));
//这种方式相当于,loopback的类型是IpAddr::V6,同时home的值是"::1"
可以使用 impl 来为结构体定义方法那样,也可以在枚举上定义方法,其使用方式与 struct 类似
impl IpAddr {
fn call(&self) {
// 在这里定义方法体
}
}
let loopback = IpAddr::V6(String::from("::1"));
loopback.call();
rust 并没有很多其他语言中有的空值功能,空值的问题在于当你尝试像一个非空值那样使用一个空值,会出现某种形式的错误。但是rust是一门追求安全的语言,所以rust 并没有空值,但是提供了一个 Option<T> 枚举,他包含两个值,一个是 None 代表空,一个是 Some ,代表非空
enum Option<T> {
None,
Some(T),
}
let some_thing = Some(5);
let absent_number : Option<i32> = None;
因为rust需要确保安全,所以 Option 和 T 不能直接进行运算
let x: i8 = 5;
let y: Option<i8> = Some(5);
//这是不允许的,即使y不是None
let sum = x + y;
match 控制符允许我们将一个值与一系列的模式相比较,并根据相匹配的模式执行相应代码,例如使用一个枚举类型,我们可以根据输入值是枚举的哪一项执行不同的操作,match的每一项返回值必须是同一个类型,如果仅返回一个值,不需要大括号进行包裹,但是如果你需要执行多个语句,则需要一个大括号进行包裹
enum Coin{
Penny,
Nickel,
Dime,
Quarter(i32),
}
fn in_cents(coin:Coin) -> u8 {
match coin {
Coin::Penny => {
println!("111");
1
},
Coin::Nickel => 5,
Coin::Dime => 10,
Coin::Quarter(state) => {
println!("{}",state);
25
},
}
}
当然如果你仅需要匹配其中的部分内容,你可以使用占位符 _ 代表其他剩余的元素
fn in_cents(coin:Coin) -> u8 {
match coin {
Coin::Penny => 1,
Coin::Nickel => 5,
_ => 2,
}
}
如果的只需要匹配其中一个元素,你还可以使用 if let 语法糖来优化,下面两种表达的效果相同
match coin {
Coin::Quarter(state) => println!("State quarter from {:?}!", state),
_ => count += 1,
}
//和上面表述相同
if let Coin::Quarter(state) = coin {
println!("State quarter from {:?}!", state);
} else {
count += 1;
}
我脑子里浮现出一些关于一种新编程语言的想法,所以我想我会尝试实现它。一位friend建议我尝试使用Treetop(Rubygem)来创建一个解析器。Treetop的文档很少,我以前从未做过这种事情。我的解析器表现得好像有一个无限循环,但没有堆栈跟踪;事实证明很难追踪到。有人可以指出入门级解析/AST指南的方向吗?我真的需要一些列出规则、常见用法等的东西来使用像Treetop这样的工具。我的语法分析器在GitHub上,以防有人希望帮助我改进它。class{initialize=lambda(name){receiver.name=name}greet=lambda{IO.puts("He
所以我在关注Railscast,我注意到在html.erb文件中,ruby代码有一个微弱的背景高亮效果,以区别于其他代码HTML文档。我知道Ryan使用TextMate。我正在使用SublimeText3。我怎样才能达到同样的效果?谢谢! 最佳答案 为SublimeText安装ERB包。假设您安装了SublimeText包管理器*,只需点击cmd+shift+P即可获得命令菜单,然后键入installpackage并选择PackageControl:InstallPackage获取包管理器菜单。在该菜单中,键入ERB并在看到包时选择
在Ruby类中,我重写了三个方法,并且在每个方法中,我基本上做同样的事情:classExampleClassdefconfirmation_required?is_allowed&&superenddefpostpone_email_change?is_allowed&&superenddefreconfirmation_required?is_allowed&&superendend有更简洁的语法吗?如何缩短代码? 最佳答案 如何使用别名?classExampleClassdefconfirmation_required?is_a
可能已经问过了,但我找不到它。这里有2个常见的情况(对我来说,在编程Rails时......)用ruby编写是令人沮丧的:"astring".match(/abc(.+)abc/)[1]在这种情况下,我得到一个错误,因为字符串不匹配,因此在nil上调用[]运算符。我想找到的是比以下内容更好的替代方法:temp="astring".match(/abc(.+)abc/);temp.nil??nil:temp[1]简而言之,如果不匹配,则简单地返回nil而不会出错第二种情况是这样的:var=something.very.long.and.tedious.to.writevar=some
我正在学习Ruby的基础知识(刚刚开始),我遇到了Hash.[]method.它被引入a=["foo",1,"bar",2]=>["foo",1,"bar",2]Hash[*a]=>{"foo"=>1,"bar"=>2}稍加思索,我发现Hash[*a]等同于Hash.[](*a)或Hash.[]*一个。我的问题是为什么会这样。是什么让您将*a放在方括号内,是否有某种规则可以在何时何地使用“it”?编辑:我的措辞似乎造成了一些困惑。我不是在问数组扩展。我明白了。我的问题基本上是:如果[]是方法名称,为什么可以将参数放在括号内?这看起来几乎——但不完全是——就像说如果你有一个方法Foo.d
1.postman介绍Postman一款非常流行的API调试工具。其实,开发人员用的更多。因为测试人员做接口测试会有更多选择,例如Jmeter、soapUI等。不过,对于开发过程中去调试接口,Postman确实足够的简单方便,而且功能强大。2.下载安装官网地址:https://www.postman.com/下载完成后双击安装吧,安装过程极其简单,无需任何操作3.使用教程这里以百度为例,工具使用简单,填写URL地址即可发送请求,在下方查看响应结果和响应状态码常用方法都有支持请求方法:getpostputdeleteGet、Post、Put与Delete的作用get:请求方法一般是用于数据查询,
Ⅰ软件测试基础一、软件测试基础理论1、软件测试的必要性所有的产品或者服务上线都需要测试2、测试的发展过程3、什么是软件测试找bug,发现缺陷4、测试的定义使用人工或自动的手段来运行或者测试某个系统的过程。目的在于检测它是否满足规定的需求。弄清预期结果和实际结果的差别。5、测试的目的以最小的人力、物力和时间找出软件中潜在的错误和缺陷6、测试的原则28原则:20%的主要功能要重点测(eg:支付宝的支付功能,其他功能都是次要的)80%的错误存在于20%的代码中7、测试标准8、测试的基本要求功能测试性能测试安全性测试兼容性测试易用性测试外观界面测试可靠性测试二、质量模型衡量一个优秀软件的维度①功能性功
目录前言滤波电路科普主要分类实际情况单位的概念常用评价参数函数型滤波器简单分析滤波电路构成低通滤波器RC低通滤波器RL低通滤波器高通滤波器RC高通滤波器RL高通滤波器部分摘自《LC滤波器设计与制作》,侵权删。前言最近需要学习放大电路和滤波电路,但是由于只在之前做音乐频谱分析仪的时候简单了解过一点点运放,所以也是相当从零开始学习了。滤波电路科普主要分类滤波器:主要是从不同频率的成分中提取出特定频率的信号。有源滤波器:由RC元件与运算放大器组成的滤波器。可滤除某一次或多次谐波,最普通易于采用的无源滤波器结构是将电感与电容串联,可对主要次谐波(3、5、7)构成低阻抗旁路。无源滤波器:无源滤波器,又称
@作者:SYFStrive @博客首页:HomePage📜:微信小程序📌:个人社区(欢迎大佬们加入)👉:社区链接🔗📌:觉得文章不错可以点点关注👉:专栏连接🔗💃:感谢支持,学累了可以先看小段由小胖给大家带来的街舞👉微信小程序(🔥)目录自定义组件-behaviors 1、什么是behaviors 2、behaviors的工作方式 3、创建behavior 4、导入并使用behavior 5、behavior中所有可用的节点 6、同名字段的覆盖和组合规则总结最后自定义组件-behaviors 1、什么是behaviorsbehaviors是小程序中,用于实现
遍历文件夹我们通常是使用递归进行操作,这种方式比较简单,也比较容易理解。本文为大家介绍另一种不使用递归的方式,由于没有使用递归,只用到了循环和集合,所以效率更高一些!一、使用递归遍历文件夹整体思路1、使用File封装初始目录,2、打印这个目录3、获取这个目录下所有的子文件和子目录的数组。4、遍历这个数组,取出每个File对象4-1、如果File是否是一个文件,打印4-2、否则就是一个目录,递归调用代码实现publicclassSearchFile{publicstaticvoidmain(String[]args){//初始目录Filedir=newFile("d:/Dev");Datebeg