Я пишу обертку Rust вокруг библиотеки C, и, делая это, я пытаюсь использовать «оптимизацию указателей на нулевое значение», упомянутую в The Book, но я не могу найти хороший способ конвертировать Option<&T>
в *const T
и Option<&mut T>
в *mut T
как то, что они описывают.Convert Option <&mut T> to * mut T
Я действительно хочу, чтобы позвонить по телефону Some(&foo) as *const _
. К сожалению, это не работает, поэтому следующая лучшая вещь, о которой я могу думать, - это черта на Option<T>
, которая позволяет мне звонить Some(&foo).as_ptr()
. Следующий код является рабочее определение и реализация для этого признака:
trait AsPtr<T> {
fn as_ptr(&self) -> *const T;
}
impl<'a, T> AsPtr<T> for Option<&'a T> {
fn as_ptr(&self) -> *const T {
match *self {
Some(val) => val as *const _,
None => ptr::null(),
}
}
}
Теперь, когда я могу назвать Some(&foo).as_ptr()
получить *const _
, я хочу, чтобы иметь возможность вызвать Some(&mut foo).as_ptr()
получить *mut _
. Ниже это новая черта я сделал, чтобы сделать это:
trait AsMutPtr<T> {
fn as_mut_ptr(&self) -> *mut T;
}
impl<'a, T> AsMutPtr<T> for Option<&'a mut T> {
fn as_mut_ptr(&self) -> *mut T {
match *self {
Some(val) => val as *mut _,
None => ptr::null_mut(),
}
}
}
Проблема, AsMutPtr
черта не будет компилироваться. Когда я пытаюсь, я получаю следующее сообщение об ошибке:
wrapper.rs:115:15: 115:20 error: cannot move out of borrowed content [E0507]
wrapper.rs:115 match *self {
| ^~~~~
wrapper.rs:115:15: 115:20 help: run `rustc --explain E0507` to see a detailed explanation
wrapper.rs:116:18: 116:21 note: attempting to move value to here
wrapper.rs:116 Some(val) => val as *mut _,
| ^~~
wrapper.rs:116:18: 116:21 help: to prevent the move, use `ref val` or `ref mut val` to capture value by reference
Я не вижу, что изменилось между двумя чертами, которые вызывают его на провал - я не думаю, что добавление mut
бы, что большая разница. Я попробовал добавить ref
, где он предложил, но это просто вызывает другую ошибку (я могу вставить это здесь, если бы это было полезно), и я бы не ожидал, что это все равно.
Может кто-нибудь объяснить мне, почему черта AsMutPtr
не работает?
Благодарим вас за это объяснение. Мне до сих пор предстоит пройти долгий путь, прежде чем я полностью пойму чекер по заимствованию, и это очень помогает. – Brian
«Я думаю, что это нормально, если он сразу преобразуется в необработанный указатель и не просачивается» → Я не уверен, что наличие двух активных псевдонимов '' '' '' '' '' '' '' '' 'наверняка кажется незаконным. Правило, которое я слышал, заключается в том, что вы никогда не должны смешивать '*' и '&', чтобы вы не попали в такие ситуации. – Veedrac