作者热门文章
- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我需要一个静态结构数组,并且这些结构包含一个 Vec。我可以管理实际值的生命周期。我收到以下错误:
: Mar23 ; cargo test
Compiling smalltalk v0.1.0 (/Users/dmason/git/AST-Smalltalk/rust)
error[E0507]: cannot move out of `dispatchTable[_]` as `dispatchTable` is a static item
--> src/minimal.rs:32:44
|
30 | let old = ManuallyDrop::into_inner(dispatchTable[pos]);
| ^^^^^^^^^^^^^^^^^^ move occurs because `dispatchTable[_]` has type `ManuallyDrop<Option<Box<Dispatch>>>`, which does not implement the `Copy` trait
error: aborting due to previous error
这是一个最小的可编译示例:
#[derive(Copy, Clone)]
struct MethodMatch {
hash: i64,
method: Option<bool>,
}
#[derive(Clone)]
pub struct Dispatch {
class: i64,
table: Vec<MethodMatch>,
}
const max_classes : usize = 100;
use std::mem::ManuallyDrop;
const no_dispatch : ManuallyDrop<Option<Box<Dispatch>>> = ManuallyDrop::new(None);
static mut dispatchTable : [ManuallyDrop<Option<Box<Dispatch>>>;max_classes] = [no_dispatch;max_classes];
use std::sync::RwLock;
lazy_static! {
static ref dispatchFree : RwLock<usize> = {RwLock::new(0)};
}
pub fn addClass(c : i64, n : usize) {
let mut index = dispatchFree.write().unwrap();
let pos = *index;
*index += 1;
replaceDispatch(pos,c,n);
}
pub fn replaceDispatch(pos : usize, c : i64, n : usize) -> Option<Box<Dispatch>> {
let mut table = Vec::with_capacity(n);
table.resize(n,MethodMatch{hash:0,method:None});
unsafe {
let old = ManuallyDrop::into_inner(dispatchTable[pos]);
dispatchTable[pos]=ManuallyDrop::new(Some(Box::new(Dispatch{class:c,table:table})));
old
}
}
我的想法是拥有
replaceDispatch
创建一个新的 Dispatch 选项对象,并将数组中的当前值替换为新的值,返回原始值,其想法是调用者将获得 Dispatch 选项值并能够使用然后删除/取消分配该对象。
.clone()
它将编译在确定的错误点之后。
但是然后原始值永远不会被删除,所以( into_inner 是多余的并且)我正在创建内存泄漏!。我是否必须手动删除它(如果我能弄清楚如何)?我以为就是这样
ManuallyDrop
买了我。从理论上讲,如果我将 Vec 中的字段副本创建为副本,则该副本将指向旧数据,因此当该对象被删除时,内存将被释放。但是(a)这看起来很脏,(b)它有点丑陋,不必要的代码(我必须处理 Some/None 情况,查看 Vec 内部等),并且(c)我看不出如何我什至会这样做!!!!
最佳答案
正如编译器告诉您的那样,您不能将值移出其他人可观察到的位置。但既然你已经准备好替换,你可以使用 std::mem::replace
:
pub fn replaceDispatch(pos: usize, c: i64, n: usize) -> Option<Box<Dispatch>> {
... table handling omitted ...
unsafe {
let old = std::mem::replace(
&mut dispatchTable[pos],
ManuallyDrop::new(Some(Box::new(Dispatch {
class: c,
table: table,
}))),
);
ManuallyDrop::into_inner(old)
}
}
Playground
Option
管理
Dispatch
的生命周期,你不需要
ManuallyDrop
完全没有,而且您也不需要
Box
:
playground .
关于rust - 如何在不获取 E0507 的情况下将包含 Vec 的结构移入/移出静态数组?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66771934/
我正在做一个项目,我的 android 在这个项目中作为一个网络服务器工作;输入带端口号的 IP 地址,打开 Web 界面,用户可以将文件上传到手机。我想在 Web 界面上显示一些图片,以便我们的界面
我是一名优秀的程序员,十分优秀!