Historia pytania:
Rust opiera się na filozofii jawnej inicjalizacji. Dla niektórych standardowych kolekcji i typów ogólnych często wymaga się, aby mieć wartość "domyślną". Jednak dla złożonych struktur często bywa niejasne, jak dokładnie je tworzyć bez parametrów. W tym celu wprowadzono trait Default, który definiuje standardowy konstruktor.
Problem:
Aby pisać uniwersalne kontenery i algorytmy, gdzie czasami oczekuje się wartości domyślnej (na przykład w Option::unwrap_or_default, Vec::resize), potrzebny jest mechanizm tworzenia instancji bez przekazywania argumentów. Jednak nie wszystkie typy nadają się do takiego konstruktora; czasami wartość domyślna może być nieoczywista i niebezpieczna.
Rozwiązanie:
default(), która zwraca pewną instancję (zazwyczaj "pustą", wyzerowaną lub z warunkami wstępnymi).Przykład kodu:
#[derive(Default, Debug)] struct Config { retries: u32, verbose: bool, } fn main() { let cfg = Config::default(); println!("{:?}", cfg); }
Kluczowe cechy:
Czy Default::default będzie wymuszony dla Option<T>, jeśli T: Default?
Nie, Optional nie wywołuje domyślnej wartości dla T automatycznie; unwrap_or_default jest wywoływane jawnie.
Czy parametry z wartościami domyślnymi mogą być ustalone przez trait Default w konstruktorze struktury?
Nie, Default tworzy całą strukturę jako całość, indywidualne pola domyślne nie mogą być zastąpione zwykłą składnią konstruktora.
Czy derive(Default) może nie zadziałać dla struktury z polami, które nie implementują Default?
Tak, derive(Default) działa tylko wtedy, gdy wszystkie pola struktury implementują Default.
Config c Default, gdzie port serwera — 0 (nieważna wartość domyślna). Program niespodziewanie uruchamia się na niewłaściwym porcie.
Zalety:
Wady:
Default dla struktury ustawień z bezpiecznymi, konsensualnymi wartościami (retries=3, verbose=false).
Zalety:
Wady: