1,了解String
String表示字符串对象类型,可以存放字符串。
fn main() {
let msg: String = String::from("你好,世界!");
println!("{}", msg);
}
你好,世界!
2,作用域
变量自声明时产生,当前块结束时丢弃。
fn main() {
//A
{
//B
let a = 3;
//C
}
//D
}
ABCD,四个地方,只有C有这个变量。
AB没有,因为还没有声明。
D没有,因为作用域已经结束了。
3,移动
变量赋值给变量,也会丢弃。
fn main() {
let msg: String = String::from("你好,世界!");
let a = msg;
//A
}
A所在的地方,已经没有msg这个变量了。
变量进入函数,也会丢弃。
fn main() {
let msg: String = String::from("你好,世界!");
hello(msg);
//A
}
fn hello(msg: String) {
println!("{}", msg);
}
基本类型没有移动的概念,而是会拷贝一份。
fn main() {
let a = 1;
hello(a);
hello(a);
hello(a);
}
fn hello(msg: i32) {
println!("{}", msg);
}
1
1
1
基本类型:整数,浮点,布尔,字符,元组。
不包括数组。
4,引用
引用是一个类型,是一个指向变量值的指针。
没有移动的概念。
fn main() {
let a = String::from("你好,世界!");
let b = &a;
hello(b);
hello(b);
hello(b);
}
fn hello(msg: &String) {
println!("{}", msg);
}
你好,世界!
你好,世界!
你好,世界!
String是String类型,
&String类型是指向String类型的指针(类型)。
a是一个变量,
&a是指向变量a的指针。
更多的时候是直接使用引用:
fn main() {
let a = String::from("你好,世界!");
hello(&a);
hello(&a);
hello(&a);
}
fn hello(msg: &String) {
println!("{}", msg);
}
你好,世界!
你好,世界!
你好,世界!
默认不能修改指向的值。
可变引用:让引用可以修改。
fn main() {
let mut a = String::from("你好,世界!");
hello(&mut a);
hello(&mut a);
hello(&mut a);
}
fn hello(msg: &mut String) {
msg.push_str("1");
println!("{}", msg);
}
你好,世界!1
你好,世界!11
你好,世界!111
可变引用的官方名称叫borrow,借用。
同一时间一个变量只能有一份可变引用。
下面这个会报错:
fn main() {
let mut s = String::from("hello");
let r1 = &mut s;
let r2 = &mut s;
println!("{}, {}", r1, r2);
}
报错。
选修:理解堆和栈
堆:数据大小不固定。比如对象。
栈:固定。比如i32就是四字节。
选修:悬垂引用
对象已经被回收了,但指针还在。
会报错。
fn main() {
let a = hello();
println!("{}", a);
}
fn hello() -> &String {
let a = String::from("hello");
&a
}
报错。