Rust 语法笔记
宏
该技术在其他语言中的类比
C/C++: #define
Java: Annotation Processing
print!("Hello, World");
#[macro_export]
#[stable(feature = "rust1", since = "1.0.0")]
#[cfg_attr(not(test), rustc_diagnostic_item = "print_macro")]
#[allow_internal_unstable(print_internals)]
macro_rules! print {
($($arg:tt)*) => {{
$crate::io::_print($crate::format_args!($($arg)*));
}};
}
基本语法
变量
let a = 10;
let mut b: i32 = 20;
let (c, mut d) = (10, 10);
const PI: f64 = 3.14;
let x = 5;
let x = x + 1;
{
let x = x * 2;
println!("The value of x in the inner scope is: {}", x);
}
println!("The value of x is: {}", x);
tip: 变量绑定,可变变量,变量解构,变量遮蔽
函数
fn add(i: i32, j: i32) -> i32 {
i + j
}
引用
Rust 通过 借用(Borrowing) 这个概念来达成上述的目的,获取变量的引用,称之为借用(borrowing)。
fn main() {
let x = 5;
let y = &x;
print!("{}", x == *y)
}
tip:& 取引用,* 解引用
字符串与切片
字符串切片引用: &str,不可修改,字符串常量属于该类型,其切片内容为二进制程序中的地址。
字符串:String,动态分配的字符串,内容可修改。
fn main() {
let s: &str = "Hello, World";
let _s1: String = s.to_string();
let s1: String = String::from(s);
let _s2: &str = &s1[..];
let s2: &str = s1.as_str();
let s3: &String = &s1;
let s4: &str = s3;
print!("{}, {}, {}, {}, {}", s, s1, s2, s3, s4)
}
元组和结构体
fn main() {
let values = (1, "str", true);
struct User {
name: String,
activate: bool,
}
let user1 = User {
name: "Bob".to_string(),
activate: true,
};
}
if 表达式
fn main() {
let condition = true;
let number = if condition {
5
} else {
6
};
println!("The value of number is: {}", number);
}
模式匹配
fn main() {
let o = Some(7);
match o {
Some(x) if x < 5 => println!("less than five: {}", x),
Some(x) => println!("{}", x),
_ => (),
}
if let Some(i) = o {
println!("This is a really long string and `{}`", i);
};
let mut stack = Vec::new();
stack.push(1);
stack.push(2);
stack.push(3);
while let Some(top) = stack.pop() {
println!("{}", top);
}
}
@绑定和解构
fn main() {
let p@ (x, y, z) = (1, 2, 3);
println!("{}, {}, {}", x, y, z);
println!("{:?}", p);
}
方法与函数
// 数据
pub struct Rectangle {
width: u32,
height: u32,
}
// 动作
impl Rectangle {
// 关联函数
pub fn new(width: u32, height: u32) -> Self {
Rectangle { width, height }
}
// 方法
pub fn width(&self) -> u32 {
return self.width;
}
pub fn height(&self) -> u32 {
return self.height;
}
}
fn main() {
let rect1 = Rectangle::new(30, 50);
println!("{}", rect1.width());
}
泛型和特征对象
trait Foo {
fn method(&self) -> String;
}
impl Foo for u8 {
fn method(&self) -> String { format!("u8: {}", *self) }
}
impl Foo for String {
fn method(&self) -> String { format!("string: {}", *self) }
}
// 通过泛型实现函数
fn static_dispatch<T: Foo>(v: T) {
println!("{}", v.method())
}
// 通过特征对象实现函数
fn dynamic_dispatch(v: &dyn Foo) {
println!("{}", v.method())
}
fn main() {
let x = 5u8;
let y = "Hello".to_string();
static_dispatch(x);
dynamic_dispatch(&y);
println!("Success!")
}
fn hatch_a_bird(typ: u8) -> Box<dyn Bird> {
match typ {
1 => Box::new(Swan),
2 => Box::new(Duck),
_ => todo!()
}
}
泛型和关联类型
struct Container(i32, i32);
trait Contains<A, B> {
fn contains(&self, c1: &A, c2: &B) -> bool;
fn first(&self) -> A;
fn last(&self) -> B;
}
impl Contains<i32, i32> for Container {
fn contains(&self, c1: &i32, c2: &i32) -> bool {
(&self.0 == c1) && (&self.1 == c2)
}
fn first(&self) -> i32 {
self.0
}
fn last(&self) -> i32 {
self.1
}
}
fn difference<A, B, C>(container: &C) -> B
where
C: Contains<A, B>,
B: std::ops::Sub<A, Output = B>,
{
container.last() - container.first()
}
fn main() {
let number_1 = 3;
let number_2 = 10;
let container = Container(number_1, number_2);
println!(
"Does container contain {} and {}: {}",
&number_1,
&number_2,
container.contains(&number_1, &number_2)
);
println!("First number: {}", container.first());
println!("Last number: {}", container.last());
println!("The difference is: {}", difference(&container));
}
struct Container(i32, i32);
trait Contains {
type A;
type B;
fn contains(&self, c1: &Self::A, c2: &Self::B) -> bool;
fn first(&self) -> Self::A;
fn last(&self) -> Self::B;
}
impl Contains for Container {
type A = i32;
type B = i32;
fn contains(&self, c1: &Self::A, c2: &Self::B) -> bool {
self.0 == *c1 && self.1 == *c2
}
fn first(&self) -> Self::A {
self.0
}
fn last(&self) -> Self::B {
self.1
}
}
fn difference<T: Contains>(container: &T) -> T::B
where
T::B: std::ops::Sub<T::A, Output = T::B>,
{
container.last() - container.first()
}
fn main() {
let number_1 = 3;
let number_2 = 10;
let container = Container(number_1, number_2);
println!(
"Does container contain {} and {}: {}",
&number_1,
&number_2,
container.contains(&number_1, &number_2)
);
println!("First number: {}", container.first());
println!("Last number: {}", container.last());
println!("The difference is: {}", difference(&container));
}