Rust 中的 Defaut 特徵是什麼?

Rust 中每個類型都從 default() 返回默認值。例如:

fn main() {
    let s = String::default();
    println!("String: {}", s);

    let int = i32::default();
    println!("Integer: {}", int);

    let str: &str = Default::default();
    println!("&str: {}", str);
}

運行結果:

String: 
Integer: 0
&str:

每種類型都實現了 default(),因此返回由 {TypeName}::default() 定義的值。爲每種類型實現的 default()的詳細信息可以在官方文檔中找到。例如,如果你看 String,它返回 String::new()。

#[stable(feature = "rust1", since = "1.0.0")]
#[rustc_const_unstable(feature = "const_default_impls", issue = "87864")]
impl const Default for String {
    /// Creates an empty `String`.
    #[inline]
    fn default() -> String {
        String::new()
    }
}

使用 #[derive(Default)] 實現 Default 特徵

通常,在向生成的對象賦值一個值時,它是這樣寫的:

struct Product {
    name: String,
    price: f64,
}

fn main() {
    let product = Product {
        name: "".to_string(),
        price: 0.0,
    };
    println!("Name: {}, Price ${}", product.name, product.price);
}

# $ cargo run
# Name: , Price $0

你需要爲它的每個屬性初始化一個值,如上所示。這很好,但是在實際的產品中,會有更多的屬性,所以一個一個地輸入值是一件痛苦的事情。

讓我們使用 Default:: Default ():

fn main() {
    let product : Product= Default::default();
    println!("Name: {}, Price ${}", product.name, product.price);
}

構建返回以下錯誤:

error[E0277]: the trait bound `Product: Default` is not satisfied
  --> src/main.rs:24:28
   |
24 |     let product : Product= Default::default();
   |                            ^^^^^^^^^^^^^^^^ the trait `Default` is not implemented for `Product`
   |
help: consider annotating `Product` with `#[derive(Default)]`
   |
12 | #[derive(Default)]
   |
For more information about this error, try `rustc --explain E0277`.
error: could not compile `default-example` due to previous error

如你所見,此錯誤的原因是沒有爲 Product 實現 Default,讓我們爲 Product 實現 Default 特徵。

#[derive(Default)] // <- Use Default.
struct Product {
    name: String,
    price: f64,
}

fn main() {
    let product : Product= Default::default();
    println!("Name: {}, Price ${}", product.name, product.price);

    let named_product = Product {
        name: "Coffee".to_string(),
        ..Default::default()
    };
    println!("Name: {}, Price ${}", named_product.name, named_product.price);
}

運行結果:

Name: , Price $0
Name: Coffee, Price $0

自己實現 Default 特徵

可以通過對 struct 實現 Default 特徵來自定義默認值。

// Remove #[derive(Default)]
struct Product {
    name: String,
    price: f64,
}

// Implement Default
impl Default for Product {
    fn default() -> Self {
        Self {
            name: "Default name".to_string(),
            price: 999.0,
        }
    }
}

fn main() {
    let product= Product::default();
    // let product : Product = Default::default(); <- Return same result 
    println!("Name: {}, Price ${}", product.name, product.price);
}

運行結果:

Name: Default name, Price $999

枚舉實現 Default 特徵

你也可以爲 enum 實現默認值:

#[derive(Default, Debug)] // Need Debug for `println` for logging.
enum Fruit {
    #[default]
    Apple,
    Banana,
    Orange,
}

fn main() {
    let fruit = Fruit::default();
    println!("{:?}", fruit);

    let banana = Fruit::Banana;
    println!("{:?}", banana);
}

運行結果:

Apple
Banana

實際產品中的使用

actix-web 的 http 的請求頭類型:RequestHead

#[derive(Debug, Clone)]
pub struct RequestHead {
    pub method: Method,
    pub uri: Uri,
    pub version: Version,
    pub headers: HeaderMap,
    pub peer_addr: Option<net::SocketAddr>,
    flags: Flags,
}

impl Default for RequestHead {
    fn default() -> RequestHead {
        RequestHead {
            method: Method::default(),
            uri: Uri::default(),
            version: Version::HTTP_11,
            headers: HeaderMap::with_capacity(16),
            peer_addr: None,
            flags: Flags::empty(),
        }
    }
}

如你所見,它爲每種屬性類型返回默認值。HTTP_11 爲 version 定義爲默認值。

本文翻譯自:

https://dev.to/yuki_ishii/what-is-default-in-rust-2a0k

本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源https://mp.weixin.qq.com/s/DpO3dl0RUvlZEa6wU5EZGg