Comments 9
const-генерики всё еще очень слабые. Тип const-генерика обязан иметь выведенный (аннотацией derive) трейт PartialEq.
Это в принципе логично — так компилятор может сравнивать константы на этапе компиляции. Но можно было бы сравнивать, и, к примеру, ссылки, ведущие на один и тот же немутабельный объект. Так можно вынести некоторые проверки на этап компиляции.
Мне кажется вы что-то перепутали, сейчас в стабильном расте тип const-generic параметра вообще может быть только числом, bool
и char
, свои типы нельзя использовать даже с #[derive(PartialEq)].
Подобное ограничение есть в паттерн матчинге, там константные паттерны работают только с типами у которых есть derive(PartialEq, Eq)
, но там и ссылки работают:
#[derive(PartialEq, Eq)]
struct Derived(i32);
struct Manual(i32);
impl Eq for Manual {}
impl PartialEq for Manual { ... }
const D: Derived = Derived(0);
const DR: &'static Derived = &Derived(0);
const M: Manual = Manual(0);
match Manual(1) {
// error: to use a constant of type `Manual` in a pattern, `Manual` must be annotated with `#[derive(PartialEq, Eq)]`
M => println!("zero???"),
_ => println!("non-zero :("),
}
match Derived(1) {
D => println!("zero!"), // ok
_ => println!("non-zero :("),
}
match &Derived(1) {
DR => println!("zero!"), // ok
_ => println!("non-zero :("),
}
Пример с деструктурирующим присваиванием я бы переписал в таком песочницо-компилируемом виде:
fn main() {
let (a, b, c, d, e);
(a, b) = (1, 2);
[c, .., d, _] = [1, 2, 3, 4, 5];
struct EF {
e: i32,
#[allow(unused)]
f: i32,
}
EF { e, .. } = EF { e: 5, f: 3 };
assert_eq!([1, 2, 1, 4, 5], [a, b, c, d, e]);
}
я удивлен, что полный перевод аж почти целые сутки провисел пока модераторы до него не добрались. ну и логика их действий понятна - боятся, что иначе весь хабр прикроют :/
Это правило должно действовать всегда.
Rust 1.59.0: встроенный ассемблер, деструктурирующее присваивание, отключение инкрементальной компиляции