2013-10-29 16 views
46

W poniższym przykładzie bardzo chciałbym przypisać wartość do każdego pola w strukturze w deklaracji pól. Alternatywnie, efektywnie pobiera jedną dodatkową instrukcję dla każdego pola, aby przypisać wartość do pól. Wszystko, co chcę zrobić, to przypisać wartości domyślne, gdy instancja struct zostanie utworzona.Czy istnieje szybszy/krótszy sposób inicjowania zmiennych w strukturze Rust?

Czy istnieje bardziej zwięzły sposób robienia tego?

struct cParams { 
    iInsertMax: i64, 
    iUpdateMax: i64, 
    iDeleteMax: i64, 
    iInstanceMax: i64, 
    tFirstInstance: bool, 
    tCreateTables: bool, 
    tContinue: bool, 
} 

impl cParams { 
    fn new() -> cParams { 
     cParams { 
      iInsertMax: -1, 
      iUpdateMax: -1, 
      iDeleteMax: -1, 
      iInstanceMax: -1, 
      tFirstInstance: false, 
      tCreateTables: false, 
      tContinue: false, 
     } 
    } 
} 

Odpowiedz

73

Można podać wartości domyślne dla swojej struktury poprzez wdrożenie cechę Default. Funkcja default wyglądałby aktualnej new funkcję:

impl Default for cParams { 
    fn default() -> cParams { 
     cParams { 
      iInsertMax: -1, 
      iUpdateMax: -1, 
      iDeleteMax: -1, 
      iInstanceMax: -1, 
      tFirstInstance: false, 
      tCreateTables: false, 
      tContinue: false, 
     } 
    } 
} 

Można wtedy instancję struct dając tylko innych niż domyślne wartości:

let p = cParams { iInsertMax: 10, ..Default::default() }; 

z niewielkimi zmianami w strukturze danych, ty może skorzystać z domyślnej implementacji domyślnej. Jeśli użyjesz #[derive(Default)] w strukturze danych, kompilator automatycznie utworzy domyślną funkcję, która wypełni każde pole jego wartością domyślną. Domyślną wartością logiczną jest false, domyślną wartością całkowitą jest 0.

Wartość domyślna liczby całkowitej wynosząca 0 jest tutaj problemem, ponieważ chcemy, aby pola z liczbami całkowitymi miały domyślnie wartość -1. Można zdefiniować nowy typ, który implementuje wartość domyślną równą -1 i użyje tego zamiast i64 w strukturze. (Nie testowałem tego, ale powinno działać).

Proponuję jednak nieznacznie zmienić strukturę danych i użyć Option<i64> zamiast i64. Nie znam kontekstu twojego kodu, ale wygląda na to, że używasz specjalnej wartości -1, aby przedstawić specjalne znaczenie "nieskończony" lub "nie ma maksimum". W Rust używamy wartości Option, aby reprezentować opcjonalnie obecną wartość. Nie ma potrzeby hackowania -1. Opcją może być None lub Some(x), gdzie x będzie tutaj Twój i64. Może to być nawet liczba całkowita bez znaku, jeśli -1 jest jedyną wartością ujemną. Domyślna wartość Option jest None, więc z proponowanymi zmianami, kod może wyglądać następująco:

#[derive(Default)] 
struct cParams { 
    iInsertMax: Option<u64>, 
    iUpdateMax: Option<u64>, 
    iDeleteMax: Option<u64>, 
    iInstanceMax: Option<u64>, 
    tFirstInstance: bool, 
    tCreateTables: bool, 
    tContinue: bool, 
} 

let p = cParams { iInsertMax: Some(10), ..Default::default() }; 
+1

Dzięki, miałem szybki odczyt, ale będę ponownie przeczytać lepszego zrozumienia. "Naturalne" wartości domyślne, których używają niektóre języki, takie jak: zero, fałsz, "" itp., Będą mi odpowiadać. Rozumiem, że istnieją szersze implikacje niż mój mały "problem" do rozwiązania. Możliwość określenia np. "iVal: i64 = 0", rozwiąże moje szersze potrzeby, ale myślę, że to się nie stanie. "# [Wyprowadzenie (domyślne)]" powinno rozwiązać większość moich potrzeb. Nie jestem pewien, dlaczego użyłem -1 w moim programie testowym, ale nie jest to potrzebne (historyczne). Byłoby bardzo użyteczne (IMHO), aby móc przypisać wartość in situ, gdzie pole jest zdefiniowane. –

+4

@BrianOh, stycznie, zaproponowano "domyślne wartości dla pól struktury" (tj. Coś takiego jak "struct Foo {val: i64 = 0}"), a więc może pojawić się w późniejszych wersjach. – huon

+0

Byłoby dobrze, gdyby zostały zaimplementowane IMO - "struct foo {....". Wprowadziłem zmiany zgodnie z sugestiami użytkownika, używając struktury, która została napisana w moim pytaniu i domyślnie. To z pewnością lepiej mi pasuje i jest o wiele bardziej zwięzłe. Będąc nieznajomym w składni, jednym z mniejszych problemów, które miałem, było poznanie składni WSZYSTKICH wartości domyślnych. IE: Użyłem "= cParams {iInsertMax: 10, ..Default :: default()};", ale naprawdę chcę, aby "iInstanceMax" również był domyślny. IMO byłoby lepiej, gdyby "# [wyprowadzenie (domyślnie)]" było częścią struktury, ale myślę, że ta alternatywa lepiej pasuje do kompilatora. –

Powiązane problemy