Правильный ответ: вы не должны делать это. Это неопределенное поведение, и оно нарушает многие предположения, сделанные компилятором при компиляции вашей программы.
Однако, возможно сделать это. Другие люди также упоминали, почему это не очень хорошая идея, но на самом деле они не показали, как будет выглядеть код, чтобы сделать что-то подобное. Даже если вы не должны делать это , это выглядит так:
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;
}
}
Если вы запустите это ... вы получите segfault. Что случилось? По сути, вы аннулировали правила памяти, пытаясь записать в область памяти, которая была помечена как неизменяемая. По сути, когда вы используете такую функцию, вы разрушаете доверие компилятора к вам, чтобы не связываться с постоянной памятью.
Именно поэтому вы никогда не должны использовать это, , особенно в публичном API , потому что, если кто-то передает невинную неизменяемую ссылку на вашу функцию, и ваша функция изменяет ее, а ссылка относится к области память не предназначена для записи, вы получите ошибку.
Короче: не пытайтесь обмануть контролера заимствований. Это там по причине.
РЕДАКТИРОВАТЬ: В дополнение к причинам, которые я только что упомянул, почему это неопределенное поведение, другая причина нарушает правила наложения ссылок. То есть, поскольку вы можете одновременно иметь как изменяемую, так и неизменяемую ссылку на переменную, это вызывает массу проблем, когда вы передаете их отдельно в одну и ту же функцию, что предполагает, что неизменяемые и изменяемые ссылки уникальны. Прочитайте эту страницу из документации Rust для получения дополнительной информации об этом.