文章来源于网络收集而来,版权归原创者所有,如有侵权请及时联系!
2.1 变量
变量包括命名变量、匿名变量,以及函数形参。除非特别声明,否则变量不可变(immutable)。目的是为了提升安全性和并发性。不可变意味着,值绑定(binding)后不能修改。
不可变是名称绑定行为,并非目标值(内存)不能修改。
fn main() { let x: i32 = 1; x = 2; ^^^^^ cannot assign twice to immutable variable }
fn main() { let mut x: i32 = 1; x = 2; }
可省略类型,通过初始值进行推断(type inference)。字面量有默认类型(例如 i32
),可添加后缀指定。
use std::mem::size_of_val; fn main() { let x = 1; // i32 let y = 2i64; // i64 let z = 3_u64; // u64 assert_eq!(4, size_of_val(&x)); assert_eq!(8, size_of_val(&y)); assert_eq!(8, size_of_val(&z)); }
fn main() { let (x, y) = (1, "abc"); assert_eq!(x, 1); assert_eq!(y, "abc"); }
变量必须初始化。可将定义和初始化分开,但在使用前必须有初始化操作。
fn main() { let x: i32; println!("{:?}", x); ^ use of possibly-uninitialized `x }
fn main() { let x: i32; x = 1; println!("{}", x); let y: i32; { y = 100; } println!("{}", y); }
未使用变量,编译器给出警告信息。如要保留,添加下划线前缀( _name
)。
仅单个下划线表示缺省变量,丢弃。
fn main() { let x = 1; ^ help: if this is intentional, prefix it with an underscore: `_x` let _y = 2; }
同一作用域(scope)内,使用相同名字再次绑定,实际是定义新变量。新定义会遮蔽(shadowing)前同名变量。
fn main() { let x: i32 = 1; println!("{:p}", &x); // 两次输出的地址不同。 let x: &str = "abc"; println!("{:p}", &x); } // 0x7ffe31b509f4 // 0x7ffe31b50a40
之所以是绑定,是因为有抽象的所有权概念。如所有权被转移(move),则该变量名视为未初始化,无法继续使用。
fn main() { let a = String::from("abc"); let b = a; println!("{}", b); println!("{}", a); }
error[E0382]: borrow of moved value: `a` | | let a = String::from("abc"); | - move occurs because `a` has type `String`, which does not implement the `Copy` trait | let b = a; | - value moved here ... | println!("{}", a); | ^ value borrowed here after move
局部变量默认是保存在栈(stack)内的值。
尽可能保存在栈内,除非大小未知需动态增长(如
String
),或手动在堆创建(如Box<T>
)。
fn main() { let s = String::from("abc"); // alloc::string println!("{}", s); } // drop
全局变量
使用 static
定义,名称大写。且必须显式声明类型,必须有初始化值。
位于 .rodata 或 .data 内。也可用于函数内,实现局部静态变量。
static X: i32 = 100; fn main() { println!("{:?}", X); }
静态可变可能导致内存安全问题(多线程),须用 unsafe
担保。
static mut X: i32 = 100; fn main() { unsafe { println!("{:?}", X); X += 1; println!("{:?}", X); } }
fn test() { static mut X: i32 = 0; unsafe { X += 1; println!("{X}"); } } fn main() { for _ in 0..3 { test(); } } /* 1 2 3 */
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论