我正在编写 Rust 对 C 库的封装,期间试图利用《The Book》中提到的“可空指针优化”,但我找不到一个好的方法将
我真正想要的是能够调用
问题在于,
我不明白两个特征之间发生了什么变化导致它失败-我认为添加“mut”不会有太大的差别。我尝试添加一个“ref”,但这只会导致不同的错误,并且我也不指望需要这个。
为什么“AsMutPtr”特征不起作用?
Option<&T>
转换为 *const T
和 Option<&mut T>
转换为 *mut T
,就像他们描述的那样。我真正想要的是能够调用
Some(&foo) as *const _
。不幸的是,这并不起作用,所以我能想到的下一个最好的方法是在 Option<T>
上定义一个 trait,使我能够调用 Some(&foo).as_ptr()
。以下代码是该 trait 的工作定义和实现:use std::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
特质无法编译。尝试时会得到以下错误:error[E0507]: cannot move out of borrowed content
--> src/lib.rs:22:15
|
22 | match *self {
| ^^^^^
| |
| cannot move out of borrowed content
| help: consider removing the `*`: `self`
23 | Some(val) => val as *mut _,
| --- data moved here
|
note: move occurs because `val` has type `&mut T`, which does not implement the `Copy` trait
--> src/lib.rs:23:18
|
23 | Some(val) => val as *mut _,
| ^^^
我不明白两个特征之间发生了什么变化导致它失败-我认为添加“mut”不会有太大的差别。我尝试添加一个“ref”,但这只会导致不同的错误,并且我也不指望需要这个。
为什么“AsMutPtr”特征不起作用?
&mut
似乎是非法的。我听说的规则是,您永远不应该混合使用*
和&
,以免陷入这种情况。 - Veedrac