Я решил реализовать протокол, который использует пару флагов, поэтому я начал определять enum
s для флагов.Однако, когда я хочу определить флаг, который имеет два значения, которые могут быть true
или false
, я получаю сообщение об ошибке:
// The protocol definition says that the flag
// can have two values true or false, so I could just use
// plain bool, but I want another name for true and false.
enum Flag {
ONE = true,
TWO = false,
}
error[E0308]: mismatched types
--> src/lib.rs:5:11
|
5 | ONE = true,
| ^^^^ expected isize, found bool
error[E0308]: mismatched types
--> src/lib.rs:6:11
|
6 | TWO = false,
| ^^^^^ expected isize, found bool
Причина, по которой я хочу использовать перечисление вместоиз двух констант является то, что флаг не является bool.Это флаг со значением представления true или false, но я не хочу смешивать обычные bool
s и flag.Если бы я использовал bool
константы, я мог бы передать значение флага каждой функции, которая принимает bool
в качестве аргумента, или использовать их в выражениях как bool
, например,
if ONE {
}
fn some_function_with_a_flag(b: bool);
// I don't want this!
some_function_with_a_flag(ONE);
Используя вместо этого enumконстант bool также предотвращает появление некоторых ошибок при использовании флага в качестве члена структуры.Есть больше флагов, определенных таким же образом, поэтому, когда я просто использую простые bool
s и константы, у меня будет структура, подобная
struct Header {
flag1: bool,
flag2: bool,
flag3: bool,
}
Компилятор примет код, где переключаются значения флага:
h = Header { flag3: ONE, flag1: TWO, flag2: ONE };
Это невозможно, когда каждый флаг имеет свой собственный тип (псевдоним для bool
).
Точка определения перечисления со значениями true
и false
просточто протокол определяет это таким образом.В моем коде я, вероятно, буду использовать логическое значение флагов, только когда данные упакованы для сериализации (это часть заголовка данных).
Хорошо, компилятор всегда предполагает, что базовый тип равен isize
.Он может быть выведен из значений, но давайте определим его
#[repr(bool)]
enum E1 {
ONE = true,
TWO = false,
}
error[E0552]: unrecognized representation hint
--> src/lib.rs:1:8
|
1 | #[repr(bool)]
| ^^^^
Похоже, мне нужно использовать u8
в качестве базового типа, а затем всегда приводить значение в bool
#[repr(u8)]
enum E2 {
ONE = 1,
TWO = 0,
}
let x = E2::ONE as bool;
Это компилируется, но кажется слишком сложным.Есть ли лучший способ определить enum
со значениями bool
?Есть ли идиома для псевдонима типа bool
, где я могу указать значение?Я мог бы просто сделать
enum Flag {
TWO,
ONE,
}
, но теперь мне снова приходится постоянно приводить значение к bool
, и порядок определения выглядит неестественным.
Поскольку значение bool будет толькоиспользовать при чтении / записи заголовка, я просто перенесу преобразование в соответствующие функции и оставлю остальную часть программы свободной от деталей реализации.