В моей программе на Rust я получаю значения формы *mut Foo из функции, написанной на C.
let x: *mut Foo = my_ffi_function();
Что вообще означает это обозначение «*mut»?
Насколько я могу судить, x — это просто указатель на изменяемую структуру Foo, такой же, как &mut Foo.
Этот код компилируется отлично:
let mut s: String = String::new();
let x: &mut String = &mut s;
let y: *mut String = x;
В чем разница между двумя формами?





*mut — это необработанный изменяемый указатель, который может иметь значение null и которым можно манипулировать C-подобными способами, например. с приведением, где &mut — это ссылка, гарантированно не равная нулю и имеющая гораздо больше ограничений.
На практике большинство полезных вещей, которые вы можете сделать с *mut, потребуют unsafe контекста, поэтому, если это вообще возможно, избегайте их или, если это не удастся, сузьте небезопасную область действия (например, обернув вызовы интерфейса FFI функциями Rust, которые получают указатель, проверьте его на достоверность и преобразуйте его в тип Rusty, обычно это либо ссылка, либо Box-тип, либо Option-обертка ссылки, чтобы сохранить «обнуляемость», одновременно предоставляя вызывающей стороне безопасный интерфейс для защиты от разыменования нулевого указателя, и позволяя вызывающему абоненту оставаться в безопасном режиме Rust вместо сброса полезных средств защиты).
&mut Foo — это ссылка , а *mut Foo — это указатель.
Во время выполнения это, по сути, одно и то же; просто адрес какого-то другого места в памяти.
Разница в том, что ссылки проверяются компилятором и всегда должны быть действительными (указывать на выделенное, ненулевое, выровненное, инициализированное значение). Чтобы помочь в этом, ссылочный тип также имеет связанное с ним время жизни (с аннотацией &'lifetime mut Foo), которое используется компилятором на этапе проверки заимствования. Это основной механизм, с помощью которого Rust обеспечивает безопасность памяти.
Напротив, компилятор не проверяет корректность указателей. Указатели могут быть нулевыми, они могут указывать на неправильно выровненные данные или вообще не указывать на какое-либо значение. Из-за этого в безопасном Rust с помощью указателей можно сделать очень мало, и поэтому доступ через указатель должен осуществляться внутри блока unsafe. Обычно этого следует избегать, поскольку код unsafe сложно получить правильно, но он может потребоваться в сложных или чувствительных к производительности сценариях (или часто в FFI).
Ваш блок кода просто демонстрирует, что ссылки можно преобразовать в указатели.
Также указатели обычно называют «необработанными указателями».