Rust 2015 vs Rust 2018
loop
loop 循环也能返回值
// old code
let x;
loop {
x = 7;
break;
}
// new code
let x = loop { break 7; };
impl Trait
表示参数以及返回值是特质类型时使用 impl Trait 语法。
// Argument Position
trait Trait {}
fn foo<T: Trait>(arg: T) {
}
fn foo(arg: impl Trait) {
}
// Return Position
trait Trait {}
impl Trait for i32 {}
fn returns_a_trait_object() -> Box<dyn Trait> {
Box::new(5)
}
fn returns_a_trait_object() -> impl Trait {
5
}
// closures
fn returns_closure() -> Box<dyn Fn(i32) -> i32> {
Box::new(|x| x + 1)
}
fn returns_closure() -> impl Fn(i32) -> i32 {
|x| x + 1
}
dyn Trait
特质类型的对象使用 dyn Trait 语法
trait Trait {}
impl Trait for i32 {}
// old
fn function1() -> Box<Trait> {
}
// new
fn function2() -> Box<dyn Trait> {
}
use std::rc::Rc;
trait Foo {}
impl Foo for i32 {
}
fn main() {
let obj: Rc<dyn Foo> = Rc::new(5);
}
关联函数和关联常量
对应于其他语言中的静态方法和静态常量
// 关联函数
struct Struct;
impl Struct {
fn foo() {
println!("foo is an associated function of Struct");
}
}
fn main() {
Struct::foo();
}
// 结构体的关联常量
struct Struct;
impl Struct {
const ID: u32 = 0;
}
fn main() {
println!("the ID of Struct is: {}", Struct::ID);
}
// 特质的关联常量
trait Trait {
const ID: u32;
}
struct Struct;
impl Trait for Struct {
const ID: u32 = 5;
}
fn main() {
println!("{}", Struct::ID);
}
..=(闭区间)
// 半开区间
// 1,2
for i in 1..3 {
println!("i: {}", i);
}
// 闭区间
// 1,2,3
for i in 1..=3 {
println!("i: {}", i);
}
Non-lexical lifetimes
fn main() {
let mut x = 5;
let y = &x;
let z = &mut x; // now ok
println!("y: {}", y); // error
}
? 操作符
// old
fn read_username_from_file() -> Result<String, io::Error> {
let f = File::open("username.txt");
let mut f = match f {
Ok(file) => file,
Err(e) => return Err(e),
};
let mut s = String::new();
match f.read_to_string(&mut s) {
Ok(_) => Ok(s),
Err(e) => Err(e),
}
}
// old
fn read_username_from_file() -> Result<String, io::Error> {
let mut f = try!(File::open("username.txt"));
let mut s = String::new();
try!(f.read_to_string(&mut s));
Ok(s)
}
// new
fn read_username_from_file() -> Result<String, io::Error> {
let mut f = File::open("username.txt")?;
let mut s = String::new();
f.read_to_string(&mut s)?;
Ok(s)
}
Slice patterns
// 匹配片段
fn main() {
greet(&[]);
// output: Bummer, there's no one here :(
greet(&["Alan"]);
// output: Hey, there Alan! You seem to be alone.
greet(&["Joan", "Hugh"]);
// output: Hello, Joan and Hugh. Nice to see you are at least 2!
greet(&["John", "Peter", "Stewart"]);
// output: Hey everyone, we seem to be 3 here today.
}
fn greet(people: &[&str]) {
match people {
[] => println!("Bummer, there's no one here :("),
[only_one] => println!("Hey, there {}! You seem to be alone.", only_one),
[first, second] => println!(
"Hello, {} and {}. Nice to see you are at least 2!",
first, second
),
_ => println!("Hey everyone, we seem to be {} here today.", people.len()),
}
}
// 匹配片段
let arr = [1, 2, 3];
assert_eq!("ends with 3", match arr {
[_, _, 3] => "ends with 3",
[a, b, c] => "ends with something else",
});