Срез известного размера времени компиляции в массив, безошибочно - PullRequest
1 голос
/ 05 апреля 2020
let some_datagram [u8; 8] = [0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00];
let a : &[u8; 2] = some_datagram[0..2];
let b : &[u8; 4] = some_datagram[2..6];
let c : &[u8; 2] = some_datagram[6..8];

Выше не будет работать, потому что some_datagram[0..2] это &[u8], а не &[u8; 2]. Это имеет смысл при использовании других типов Range*, когда начальная / конечная точки неизвестны во время компиляции. Я знаю, что есть реализация TryInto для &[u8] в &[u8; n], но, поскольку все это известно во время компиляции, мне мешает иметь дело с ошибкой, которая, как я знаю, не может произойти.

Есть ли альтернативный метод, кроме [], который возвращает массив фиксированного размера? Возможно стандартный макрос?

1 Ответ

1 голос
/ 05 апреля 2020

Ящик array_macro экспортирует макрос array!, который позволяет создавать массивы с помощью обратного вызова по индексам нового массива. Документация иллюстрирует это на следующем примере:

assert_eq!(array![|x| x; 3], [0, 1, 2]);

В вашем случае вы можете sh преобразовать срез в массив с помощью операторов

let a : &[u8; 2] = array![|i| some_datagram[i    ]; 2];
let b : &[u8; 4] = array![|i| some_datagram[i + 2]; 4];
let c : &[u8; 2] = array![|i| some_datagram[i + 6]; 2];

Является ли это более или менее удобочитаемее, чем использование стандартной реализации TryInto и .unwrap, это вопрос мнения. Поскольку это ящик стороннего производителя, вам также следует учитывать тот факт, что большинство разработчиков, читающих этот код, не обязательно будут знакомы с тем, что делает макрос array!.

...