Структуру с правильными размерами в виде нулевых копий можно сделать с помощью stdlib
и общей функции.
В приведенном ниже примере есть функция многократного использования, называемая any_as_u8_slice
, а не convert_struct
, так как это утилита для создания роли и создания срезов.
Обратите внимание, что вопрос задает вопрос о преобразовании , этот пример создает только разрешенный для чтения срез, поэтому имеет преимущество в том, что не нужно копировать память.
Heres рабочий пример, основанный на вопрос:
unsafe fn any_as_u8_slice<T: Sized>(p: &T) -> &[u8] {
::std::slice::from_raw_parts(
(p as *const T) as *const u8,
::std::mem::size_of::<T>(),
)
}
fn main() {
struct MyStruct {
id: u8,
data: [u8; 1024],
}
let my_struct = MyStruct { id: 0, data: [1; 1024] };
let bytes: &[u8] = unsafe { any_as_u8_slice(&my_struct) };
// tcp_stream.write(bytes);
println!("{:?}", bytes);
}
Примечание 1) даже несмотря на 3-й партии ящиков может быть лучше в некоторых случаях, это такая примитивная операция, что ее полезно умеют делать в ржавчине.
примечание 2) на момент написания (Rust 1.15), нет поддержки для const
функций. Как только это произойдет, можно будет отбросить в массив фиксированного размера вместо среза.
Примечания 3) функции any_as_u8_slice
отмечена unsafe
, потому что любая обивка байты в struct
могут быть инициализирована память (дают неопределенное поведение). Если бы был способ, чтобы входные аргументы использовали только структуры, которые были #[repr(packed)]
, тогда это могло быть безопасным.
В противном случае функция достаточно безопасна, поскольку она предотвращает переполнение буфера, поскольку выход доступен только для чтения, фиксированное количество байтов и его время жизни привязано к входу.
Если вам нужна версия, которая вернула &mut [u8]
, это было бы очень опасно, так как модификация могла бы легко создавать непоследовательные/поврежденные данные.
Кажется, это полезно в моем случае !! Спасибо за ответ! – agatana
Стоит отметить, что это не прямое преобразование, в то время как кодирование/декодирование использует двоичный формат, это не просто доступ к памяти структуры (которая может рассматриваться как хорошая и плохая вещь) в зависимости от того, что вы хотите, он выполняет некоторые преобразования. Например, Bincode также выполняет преобразование в endian. – ideasman42