枣庄建设局网站,做公司门户网站,自己做的网站与ie不兼容,百度seo工作室不管学什么语言好像都得从变量开始#xff0c;不过只需要懂得大概就可以了。 但在Rust里不先把变量研究明白后面根本无法进行… 变量绑定
变量赋值❌ 变量绑定✔️ Rust中没有“赋值”一说#xff0c;而是称为绑定。
int a 3; //C中的变量赋值
a 3; //python中的… 不管学什么语言好像都得从变量开始不过只需要懂得大概就可以了。 但在Rust里不先把变量研究明白后面根本无法进行… 变量绑定
变量赋值❌ 变量绑定✔️ Rust中没有“赋值”一说而是称为绑定。
int a 3; //C中的变量赋值
a 3; //python中的变量赋值
var a 3; //JavaScript中的变量赋值
let foo 3; //Rust中的变量绑定这里就涉及 Rust 最核心的原则——所有权简单来讲任何内存对象都是有主人的而且一般情况下完全属于它的主人绑定就是把某个内存对象绑定给一个变量让这个变量成为它的主人在这种情况下该对象之前的主人就会丧失对该对象的所有权。
变量的可变性
Rust 的变量在默认情况下是不可变的。这是 Rust 语言的特性之一有助于提升安全和性能。而通过 mut 关键字即可以指定某个变量为可变的。
// 导入 io 模块其中包含了处理输入输出的标准库
use std::io;fn main() {// 声明不可变变量 foo开辟内存对象值为1并绑定给它let foo 1; //编译器进行类型推断这里推断出是int类型// 声明另一个不可变变量 bar// 开辟新的内存对象并将 foo 绑定的值 1 拷贝进去然后绑定给bar// 不可变变量在定义时内存对象在开辟时就需要进行值的绑定let bar foo;// 检查 bar 绑定值是否为数字 1if bar 1{ 这里的 println! 整体是一个宏功能为打印一行文字println!(绑定成功)}
}在上面的例子中变量 foo和 bar 均为不可变变量一旦为它绑定值就不能再进行修改。 选择可变还是不可变更多的还是取决于实际使用场景例如不可变可以带来安全性但是丧失了灵活性和性能而可变变量最大的好处就是使用上的灵活性和性能上的提升。 // 导入 io 模块其中包含了处理输入输出的标准库
use std::io;fn main() {println!(我要读取输入);println!(请输入);// 使用 mut 关键字声明可变变量 rece类型为 String// 并通过 String 类型内置的默认构造函数初始化为空字符串let mut rece String::new(); //编译器从右值推断变量是string类型// 使用 io 模块下的 stdin().read_line 方法从标准输入读取一行内容到 rece 变量绑定的内存中// rece 需要是可变变量根本原因是 rece 绑定的内存需要可变因为要按照用户输入内容进行修改// 使用 是因为此处传递的是参数变量绑定的内存而并非是内存中的值这样子方便可以在程序的任何位置进行修改// 使用 expect 函数处理错误如果发生错误则打印“无法读取行”io::stdin().read_line(mut rece).expect(无法读取行);// 打印读取到的输入内容// {} 是占位符输出的是后面变量的值。多个{}就按顺序对应多个变量println!(你输入的是{}, rece);
}在上面的例子中rece 为一个可变变量它的值可以进行修改。 这种做法是为了避免无法预期的错误发生在我们的变量上一个变量往往被多处代码所使用其中一部分代码假定该变量的值永远不会改变而另外一部分代码却无情的改变了这个值在实际开发过程中这个错误是很难被发现的特别是在多线程编程中。 变量未使用引起的错误
如果你创建了一个变量却不在任何地方使用它Rust 通常会给你一个警告因为这可能会是个 BUG。但是有时创建一个不会被使用的变量是有用的比如你正在设计原型或刚刚开始一个项目。这时你希望告诉 Rust 不要警告未使用的变量为此可以用下划线作为变量名的开头
fn main() {//let foo;//let bar;//像上面这样如果变量定义了但不使用就会发生警告let _foo;let _bar;//像上面这样告诉编译器这两个变量是故意不使用的就不会警告
}变量遮蔽特性
Rust 允许声明相同的变量名在后面声明的变量会“遮蔽”掉前面声明的如下所示
fn main() {let x 5; //不可变变量绑定的内存不可更改内存的值不可更改。//假设绑定的内存对象为1号// 在main函数的作用域内对之前的x进行遮蔽let x x 1; //新的同名不可变变量进行遮蔽//绑定了新的内存对象假设为2号该内存对象中的值为(1号内存对象中存储的值1)//这一行后面相同作用域的程序中x都指代的是2号内存对象{// 在当前的花括号作用域内对上面最近的x进行遮蔽let x x * 2;println!(The value of x in the inner scope is: {}, x);}println!(The value of x is: {}, x);
}这个程序首先将数值 5 绑定到 x然后通过重复使用 let x 来遮蔽之前的 x并取原来的值加上 1所以 x 的值变成了 6。第三个 let 语句同样遮蔽前面的 x取之前的值并乘上 2得到的 x 最终值为 12。当运行此程序将输出以下内容
The value of x in the inner scope is: 12
The value of x is: 6注意 这和 mut 声明可变变量的使用是不同的。第二个 let 生成了完全不同的新变量因为它开辟了新的内存对象两个变量只是恰好拥有同样的名称但底层的内存对象是不同的。而 mut 声明的变量可以修改同一个内存地址上的值并不会产生新的内存对象。
变量遮蔽的用处在于如果你在某个作用域内无需再使用之前的变量在被遮蔽后无法再访问到之前的同名变量就可以重复的使用变量名字而不用绞尽脑汁去想更多的名字。
变量遮蔽不仅可以作用于相同类型的变量而且可以方便我们在改变变量类型的情况下仍然使用同样的名字
//将输入的字符串转换成数字
fn main(){println!(输入一个大于0的数字);let mut guess String::new();//guess为可变变量绑定的内存不可更改内存存储的值可更改//从这里往后的guess都是string类型io::stdin().read_line(mut guess).expect(无法读取行);// 报错string不能和int进行比较// if guess 0 {// print!(数字大于0!)// }// 类型转换绑定新的内存对象内存类型是i32类型(int类型)可以进行比较// guess.trim().parse() 将字符串转换为数字用guess绑定的新内存对象存储// 同名不同内存let guess:i32 guess.trim().parse().expect(转换失败);//从这里往后的guess都是i32类型if guess 0 {print!(数字大于0!);}
}// 思考为什么上面例子中的这句代码不能写成下面这样进行类型推断
let guess guess.trim().parse().expect(转换失败);// 因为可变变量只有一块内存内存类型是在声明时确定的并且一旦声明其类型就不能改变类型推断也不行。
// guess已经绑定了string类型的内存对象
// 把一个数字存给string类型的内存对象是不允许的
// 错误原因是进行了错误类型赋值。
// 要改变可变变量的类型就要靠注明了类型的变量遮蔽来实现。不可变变量内存不可改内存的值不可改。 可变变量内存不可改内存的值可改。