Чи існує швидший / коротший спосіб ініціалізації змінних у структурі Rust?


102

У наступному прикладі я б вважав за краще призначити значення кожному полі в структурі в декларації полів. Крім того, воно ефективно приймає по одній додатковій заяві для кожного поля, щоб призначити значення полям. Все, що я хочу зробити, це присвоїти значення за замовчуванням, коли структура створена.

Чи є більш складний спосіб зробити це?

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,
        }
    }
}

Відповіді:


161

Можна вказати значення за замовчуванням для вашої структури, застосувавши Defaultознаку. defaultФункція буде виглядати поточну newфункцію:

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

Потім можна інстанціювати структуру, вказавши лише значення, що не знаходяться за замовчуванням:

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

З деякими незначними змінами у вашій структурі даних ви можете скористатися автоматично отриманою типовою реалізацією. Якщо ви використовуєте #[derive(Default)]структуру даних, компілятор автоматично створить для вас функцію за замовчуванням, яка заповнює кожне поле своїм значенням за замовчуванням. Булеве значення за замовчуванням - помилкове, інтегральне значення за замовчуванням - 0.

Тут є проблемою значення за замовчуванням для цілого числа 0, оскільки ви хочете, щоб цілі поля за замовчуванням були -1. Ви можете визначити новий тип, який реалізує значення за замовчуванням -1 та використовувати це замість i64вашої структури. (Я цього не перевіряв, але це має працювати).

Однак я б радив трохи змінити структуру даних і використовувати Option<i64>замість цього i64. Я не знаю контексту вашого коду, але, схоже, ви використовуєте спеціальне значення -1 для позначення спеціального значення "нескінченний" або "немає макс". У Rust, ми використовуємо a, Optionщоб представити необов'язково присутнє значення. Немає потреби в злому -1. Опція може бути будь-якою Noneабо Some(x)де x буде вашим i64тут. Це може бути навіть непідписане ціле число, якби -1 було єдиним від’ємним значенням. Значенням за замовчуванням Optionє None, тому із запропонованими змінами ваш код може виглядати так:

#[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
Дякую, я швидко прочитав, але перечитаю, щоб краще зрозуміти. "Природні" типові параметри, якими користуються деякі мови, такі як я вважаю нульовими, неправдивими "," тощо. Я розумію, що є більш широкі наслідки, ніж моя маленька "проблема" для вирішення. Можливість констатувати, наприклад. "iVal: i64 = 0" вирішив би мої ширші потреби, але, мабуть, цього не відбудеться. "# [Похідне (за замовчуванням)]" має вирішити більшість моїх бажань. Я не впевнений, чому я використовував -1 у своїй тестовій програмі, але вона не потрібна (історична). Було б дуже корисно (IMHO) мати можливість призначити значення in situ, де визначено поле.
Брайан Ой

9
@BrianOh, дотично "запропоновані" значення за замовчуванням для структурних полів "(тобто щось подібне struct Foo { val: i64 = 0 }), і вони можуть з'являтися в пізніших версіях.
хун

Було б добре, якби це було реалізовано IMO - "struct foo {....". Я вніс зміни, як ви запропонували, використовуючи структуру, як написано в моєму запитанні, і за замовчуванням. Це, безумовно, підходить мені краще і набагато більш стисло. Будучи незнайомим із синтаксисом, одна незначна проблема, яку я мав, - це не знати синтаксис для ВСІХ за замовчуванням. IE: Я використовував "= cParams {iInsertMax: 10, ..Default :: default ()};", але я фактично хочу, щоб "iInstanceMax" також був за замовчуванням. ІМО, бажано, щоб "# [деривація (за замовчуванням)]" була частиною структури, але я думаю, що альтернатива краще підходить компілятору.
Брайан Ой

2
Велике спасибі за це. IMHO за замовчуванням має бути типовими параметрами. IE. Я не думаю, що потрібно вказувати за замовчуванням: за замовчуванням тощо, тощо. Я також думаю, що полям слід мати можливість присвоювати значення там, де вони визначені. Це якраз з мого простого погляду, і я розумію, що Іржа створена таким чином, щоб бути безпечною, і що є набагато ширша перспектива, ніж моя. Коли хтось вивчає мову (або принаймні я), поточна реалізація здається трохи громіздкою. Іржа - це не проста мова ІМХО, і чим більше можливо зробити її спрощення, тим краще для мене.
Брайан Ой

2
Чи потрібно визначати параметри за замовчуванням для всіх полів при впровадженні Defaultструктури?
Меттью Стівенсон
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.