Что является современным аналогом устаревшего std::raw::Repr?
Я просматриваю старый (~2014) код Rust и вижу этот блок кода:
fn compile(self, func:&UncompiledFunction<'a>) -> &'a Val {
unsafe {
use std::raw::Repr;
use std::mem::transmute as cast;
let slice = self.repr();
let ty = <&'a str as Compile<'a>>::get_type();
let structure = Val::new(func, &ty);
let offset_data = cast::<_, usize>(&slice.data) - cast::<_, usize>(&slice);
let offset_len = cast::<_, usize>(&slice.len) - cast::<_, usize>(&slice);
func.insn_store_relative(structure, offset_data, func.insn_of(mem::transmute::<_, isize>(slice.data)));
func.insn_store_relative(structure, offset_len, func.insn_of(slice.len));
structure
}
}
Согласно документации и этой дискуссии на GitHub std::raw::Repr
а также std::raw::Slice
устарели в пользу std::slice
функции
Как человек с только начинающим пониманием библиотеки std, я не уверен, как перевести эти конкретные строки из приведенного выше блока:
let slice = self.repr(); // `self` here is a `static str`
let offset_data = cast::<_, usize>(&slice.data) - cast::<_, usize>(&slice);
let offset_len = cast::<_, usize>(&slice.len) - cast::<_, usize>(&slice);
Я просматривал документацию дляRepr
с надеждой, что я мог бы провести аналогию с какой-то функцией в std::slice
семья, но мне ничего не сразу понятно.
Я надеюсь, что кто-то может объяснить мне, что именно Repr
делает (на другом языке) и какой может быть более обновленный подход.
1 ответ
За x
типа &[T]
или же &str
:
- Замена для
x.repr().data
являетсяx.as_ptr()
, - Замена для
x.repr().len
являетсяx.len()
, - Замена для трансмутации из
std::raw::Slice
вернуться к&[T]
или же&str
являетсяstd::slice::from_raw_parts
(и опциональноstd::str::from_utf8_unchecked
).
Однако этот код не просто получает доступ к указателю и длине, он берет адрес этих полей, чтобы вычислить их смещение, предположительно для того, чтобы впоследствии выполнить некоторые небезопасные / непроверенные операции чтения или записи в память.
Бесполезный ответ - не делай этого. std::raw::Slice
был удален именно потому, что мы не хотели стабилизировать точное расположение памяти &[T]
а также &str
, Если это вообще возможно, рассмотрите возможность рефакторинга кода, чтобы не выполнять эти непроверенные обращения к памяти, а вместо этого, например, заменить всю строку на std::str::from_utf8_unchecked(std::slice::from_raw_parts(new_pointer, new_len))
,
Практический ответ заключается в том, что структура памяти вряд ли изменится, и вы, вероятно, будете в порядке, если будете жестко программировать:
let offset_data = 0;
let offset_len = std::mem::size_of::<usize>();