Rust语言学习笔记(3)

泛型(generics)

// 泛型枚举(generic enums)
enum Option<T> {
    Some(T),
    None,
}
let x: Option<i32> = Some(5);
let y: Option<f64> = Some(5.0f64);
enum Result<T, E> {
    Ok(T),
    Err(E),
}
// 泛型函数(generic functions)
fn takes_anything<T>(x: T) {
    // do something with x
}
fn takes_two_of_the_same_things<T>(x: T, y: T) {
    // ...
}
fn takes_two_things<T, U>(x: T, y: U) {
    // ...
}
// 泛型结构体(generic structs)
struct Point<T> {
    x: T,
    y: T,
}
let int_origin = Point { x: 0, y: 0 };
let float_origin = Point { x: 0.0, y: 0.0 };
impl<T> Point<T> {
    fn swap(&mut self) {
        std::mem::swap(&mut self.x, &mut self.y);
    }
}

特质(traits)

  • 特质大致相当于Java和C#中的接口。
  • 特质内通常只包含方法的签名,实现某个特质需要实现特质内的所有方法。
  • 特质内的方法可以有缺省实现。缺省方法(default methods)中的实现可以被覆盖(overridden)。
  • 一个特质可以继承另一个特质。
  • 使用deriving特性可以自动实现某些特质。
// 特质
trait HasArea {
    fn area(&self) -> f64;
}
struct Circle {
    x: f64,
    y: f64,
    radius: f64,
}
// 在结构体中实现特质
impl HasArea for Circle {
    fn area(&self) -> f64 {
        std::f64::consts::PI * (self.radius * self.radius)
    }
}
// 为其他类型实现特质
trait HasArea {
    fn area(&self) -> f64;
}
impl HasArea for i32 {
    fn area(&self) -> f64 {
        println!("this is silly");
        *self as f64
    }
}
5.area();
// 特质的缺省方法
trait Foo {
    fn is_valid(&self) -> bool;
    fn is_invalid(&self) -> bool { !self.is_valid() }
}
struct UseDefault;
impl Foo for UseDefault {
    fn is_valid(&self) -> bool {
        println!("Called UseDefault.is_valid.");
        true
    }
}
struct OverrideDefault;
impl Foo for OverrideDefault {
    fn is_valid(&self) -> bool {
        println!("Called OverrideDefault.is_valid.");
        true
    }
    fn is_invalid(&self) -> bool {
        println!("Called OverrideDefault.is_invalid!");
        true // overrides the expected value of is_invalid()
    }
}
let default = UseDefault;
assert!(!default.is_invalid()); // prints "Called UseDefault.is_valid."
let over = OverrideDefault;
assert!(over.is_invalid()); // prints "Called OverrideDefault.is_invalid!"
// 特质的继承(inheritance)
trait Foo {
    fn foo(&self);
}
trait FooBar : Foo {
    fn foobar(&self);
}
struct Baz;
impl Foo for Baz {
    fn foo(&self) { println!("foo"); }
}
impl FooBar for Baz {
    fn foobar(&self) { println!("foobar"); }
}
// deriving
#[derive(Debug)]
struct Foo;

fn main() {
    println!("{:?}", Foo);
}

特质边界(trait bounds)与特质对象(trait objects)

  • 特质可以被用于泛型约束以实现静多态(static dispatch)。用于泛型约束的特质被称作泛型的特质边界。
  • 特质可以被用作类型以实现动多态(dynamic dispatch)。特质类型的引用被称作特质对象。
  • 一个泛型类型可以指定多个特质边界,复杂情况下还可以使用where子句。
// 特质的应用
trait HasArea {
    fn area(&self) -> f64;
}
struct Circle {
    x: f64,
    y: f64,
    radius: f64,
}
impl HasArea for Circle {
    fn area(&self) -> f64 {
        std::f64::consts::PI * (self.radius * self.radius)
    }
}
struct Square {
    x: f64,
    y: f64,
    side: f64,
}
impl HasArea for Square {
    fn area(&self) -> f64 {
        self.side * self.side
    }
}
// 泛型函数的特质边界,静多态
fn print_area_static<T: HasArea>(shape: &T) {
    println!("This shape has an area of {}", shape.area());
}
// 特质对象,动多态
fn print_area_dynamic(shape: &HasArea) {
    println!("This shape has an area of {}", shape.area());
}
fn main() {
    let c = Circle {
        x: 0.0f64,
        y: 0.0f64,
        radius: 1.0f64,
    };
    let s = Square {
        x: 0.0f64,
        y: 0.0f64,
        side: 1.0f64,
    };
    print_area_static(&c);  // This shape has an area of 3.141592653589793
    print_area_static(&s);  // This shape has an area of 1
    print_area_dynamic(&c); // This shape has an area of 3.141592653589793
    print_area_dynamic(&s); // This shape has an area of 1
}
// 泛型结构体的特质边界
struct Rectangle<T> {
    x: T,
    y: T,
    width: T,
    height: T,
}
impl<T: PartialEq> Rectangle<T> {
    fn is_square(&self) -> bool {
        self.width == self.height
    }
}
fn main() {
    let mut r = Rectangle {
        x: 0,
        y: 0,
        width: 47,
        height: 47,
    };
    assert!(r.is_square());
    r.height = 42;
    assert!(!r.is_square());
}
// 多重特质边界
fn foo<T: Clone>(x: T) {
    x.clone();
}
use std::fmt::Debug;
fn foo<T: Clone + Debug>(x: T) {
    x.clone();
    println!("{:?}", x);
}
// where子句
use std::fmt::Debug;
fn foo<T: Clone, K: Clone + Debug>(x: T, y: K) {
    x.clone();
    y.clone();
    println!("{:?}", y);
}
fn bar<T, K>(x: T, y: K) where T: Clone, K: Clone + Debug {
    x.clone();
    y.clone();
    println!("{:?}", y);
}
fn main() {
    foo("Hello", "world");
    bar("Hello", "world");
}

Drop特质

// 实现Drop特质
struct Firework {
    strength: i32,
}
impl Drop for Firework {
    fn drop(&mut self) {
        println!("BOOM times {}!!!", self.strength);
    }
}
fn main() {
    let firecracker = Firework { strength: 1 };
    let tnt = Firework { strength: 100 };
}
// BOOM times 100!!!
// BOOM times 1!!!

通用函数调用语法(universal function call syntax)

// 通用函数调用语法
trait Foo {
    fn foo() -> i32;
}
struct Bar;
impl Bar {
    fn foo() -> i32 {
        20
    }
}
impl Foo for Bar {
    fn foo() -> i32 {
        10
    }
}
fn main() {
    assert_eq!(10, <Bar as Foo>::foo());
    assert_eq!(20, Bar::foo());
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值