Что является современным аналогом устаревшего std :: raw :: Repr? - PullRequest
0 голосов
/ 28 сентября 2018

Я просматриваю старый (~ 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 Ответ

0 голосов
/ 01 октября 2018

Для 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>();
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...