Есть ли способ сделать неизменяемую ссылку изменяемой?

Существует ряд причин для определения приоритетов тестов, не последним из которых является производительность, для чего предназначен JUnit Max. Иногда бывает полезно проводить очень медленные тесты в своем собственном модуле, чтобы вы могли быстро получить отзывы от тех тестов, которые не страдают от тех же тяжелых зависимостей. Заказ также полезен для отслеживания сбоев в тестах, которые не являются полностью автономными.

0
задан Peter Hall 17 January 2019 в 15:08
поделиться

2 ответа

Есть ли способ сделать неизменяемую ссылку изменяемой?

Нет.

Вы могли бы написать небезопасный код Rust, чтобы заставить типы выстраиваться в линию, но код на самом деле был бы небезопасным и приводил к неопределенному поведению . Вы не хотите этого.


Для вашей конкретной проблемы см .:

0
ответ дан Shepmaster 17 January 2019 в 15:08
поделиться

Правильный ответ: вы не должны делать это. Это неопределенное поведение, и оно нарушает многие предположения, сделанные компилятором при компиляции вашей программы.

Однако, возможно сделать это. Другие люди также упоминали, почему это не очень хорошая идея, но на самом деле они не показали, как будет выглядеть код, чтобы сделать что-то подобное. Даже если вы не должны этого не делать , это будет выглядеть так:

unsafe fn very_bad_function<T>(reference: &T) -> &mut T {
    let const_ptr = reference as *const T;
    let mut_ptr = const_ptr as *mut T;
    &mut *mut_ptr
}

По сути, вы конвертируете постоянный указатель в изменяемый, а затем превращаете изменяемый указатель в ссылка.

Вот один из примеров того, почему это очень небезопасно и непредсказуемо:

fn main() {
    static THIS_IS_IMMUTABLE: i32 = 0;
    unsafe {
        let mut bad_reference = very_bad_function(&THIS_IS_IMMUTABLE);
        *bad_reference = 5;
    }
}

Если вы запустите это ... вы получите ошибку. Что случилось? По сути, вы аннулировали правила памяти, пытаясь записать в область памяти, которая была помечена как неизменяемая. По сути, когда вы используете такую ​​функцию, вы нарушаете доверие, которое компилятор оказал вам, чтобы не связываться с постоянной памятью.

Именно поэтому вы никогда не должны использовать это, , особенно в публичном API , потому что, если кто-то передает невинную неизменяемую ссылку на вашу функцию, и ваша функция мутирует ее, а ссылка на область память не предназначена для записи, вы получите сегфо.

Короче говоря: не пытайтесь обмануть контролера заимствований. Это там по причине.

РЕДАКТИРОВАТЬ: В дополнение к причинам, которые я только что упомянул, почему это неопределенное поведение, еще одна причина - нарушение правил наложения ссылок. То есть, поскольку вы можете одновременно иметь как изменяемую, так и неизменяемую ссылку на переменную, это вызывает массу проблем, когда вы передаете их отдельно в одну и ту же функцию, что предполагает, что неизменяемые и изменяемые ссылки уникальны. Прочитайте эту страницу из документации Rust для получения дополнительной информации об этом.

0
ответ дан ThatOneDeveloper 17 January 2019 в 15:08
поделиться
Другие вопросы по тегам:

Похожие вопросы: