Сложность агрегирования матчей с | - PullRequest
1 голос
/ 09 июля 2020

Я пытаюсь упаковать столбчатые данные, чтобы их можно было отправить на сервер.

Я хотел иметь возможность передавать любой подходящий вектор функции отправки, поэтому я сделал это (краткая версия) :

enum Column {
    Short(Vec<i16>),
    Int(Vec<i32>),
}

impl Column {
    fn as_bytes(&mut self) -> &[u8] {
        use Column::*; // weird
        match self {
            Short(vec) => unsafe { (vec.align_to::<u8>()).1 }, //why the ::?
            Int(vec) => unsafe { (vec.align_to::<u8>()).1 },
        }
    }
}

Работает нормально. Однако, если я перепишу совпадение с помощью канала или:

impl Column {
    fn as_bytes_succinct(&mut self) -> &[u8] {
        use Column::*;

        match self {
            Short(vec) | Int(vec) => unsafe { (vec.align_to::<u8>()).1 },
        }
    }
}

, я получу

ожидаемое i16, найдено i32

Чем / чем краткое написание отличается от явного?

1 Ответ

3 голосов
/ 10 июля 2020

Rust - это статически типизированный язык, поэтому каждый объект имеет известный тип во время компиляции. Ваше совпадение в последнем примере эквивалентно следующему коду:

let vec: Vec<???> = match self {
    Short(v) | Int(v) => v,
};

unsafe { vec.align_to() }.1

Какой тип типа должен иметь vec? Более того, есть 2 разных пути для align_to, т.е. <[i16]>::align_to и <[i32]>::align_to, которые могут иметь другую реализацию с функцией specialization.

...