Я относительно новичок в Rust. Этот вопрос оказался довольно длинным, поэтому я начну с подведения итогов: Какое решение вы предпочитаете? Есть ли у вас какие-либо идеи или замечания?
Мой код не компилируется, потому что строки 6 (prev = curr
) и 12 (bar(...)
) используют переменные, которые, по мнению компилятора, возможно, не инициализированы. Как программист, я знаю, что нет причин для беспокойства, потому что строки 6 и 12 не выполняются во время первой итерации.
let mut curr: Enum;
let mut prev: Enum;
for i in 0..10 {
if i > 0 {
prev = curr;
}
curr = foo();
if i > 0 {
bar(&curr, &prev);
}
}
Я понимаю, что есть предел того, что вы можете ожидать от компилятора до знать. Поэтому я придумал 3 разных способа ответить на ограничение безопасности языка.
1) Инициализировать и перестать слишком много думать
Я мог бы просто инициализировать переменные произвольными значениями . Риск состоит в том, что сопровождающий может ошибочно подумать, что эти первоначальные, надеюсь, неиспользуемые значения имеют какое-то важное значение. Строки 1-2 станут:
let mut curr: Enum = Enum::RED; // Just an arbitrary value!
let mut prev: Enum = Enum::BLUE; // Just an arbitrary value!
2) Добавьте None
значение к Enum
Строки 1-2 станут
let mut curr: Enum = Enum::None;
let mut prev: Enum = Enum::None;
Причина, по которой мне не нравится это решение, состоит в том, что теперь я добавил новое возможное и ненатуральное значение в свое перечисление. Для моей собственной безопасности мне придется добавить проверки утверждений и сопоставления к foo()
и bar()
, а также к любой другой функции, которая использует Enum
.
3) Option<Enum>
Я думаю, что это решение является наиболее очевидным, но оно делает код длиннее и труднее для понимания.
Строки 1-2 станут
let mut curr: Option<Enum> = None;
let mut prev: Option<Enum> = None;
На этот раз None
принадлежит Option
, а не Enum
. Оператор innocent prev = curr
станет
prev = match curr {
Some(_) => curr,
None => panic!("Ah!")
};
, а наивный вызов bar()
превратится в
match prev {
Some(_) => bar(&curr, &prev),
None => panic!("Oy!")
};
Вопросы: Какое решение вы предпочитаете ? Есть ли у вас идеи или замечания?