我正在尝试创建一种方法,该方法可以返回对Data
的引用,该引用可以在常量全局数组中,也可以在项中的Option
内部。生存期当然是不同的,但是可以安全地假设数据的生存期至少与项目的生存期一样长。在执行此操作时,我希望编译器在执行任何错误操作时发出警告,但它会生成错误的指令,并且程序会因SIGILL
而崩溃。
具体来说,我的以下代码在Rust 1.27.2中失败:
#[derive(Debug)]
pub enum Type {
TYPE1,
TYPE2,
}
#[derive(Debug)]
pub struct Data {
pub ctype: Type,
pub int: i32,
}
#[derive(Debug)]
pub struct Entity {
pub idata: usize,
pub modifier: Option<Data>,
}
impl Entity {
pub fn data(&self) -> &Data {
if self.modifier.is_none() {
&DATA[self.idata]
} else {
self.modifier.as_ref().unwrap()
}
}
}
pub const DATA: [Data; 1] = [Data {
ctype: Type::TYPE2,
int: 1,
}];
fn main() {
let mut itemvec = vec![Entity {
idata: 0,
modifier: None,
}];
eprintln!("vec[0]: {:p} = {:?}", &itemvec[0], itemvec[0]);
eprintln!("removed item 0");
let item = itemvec.remove(0);
eprintln!("item: {:p} = {:?}", &item, item);
eprintln!("modifier: {:p} = {:?}", &item.modifier, item.modifier);
eprintln!("DATA: {:p} = {:?}", &DATA[0], DATA[0]);
let itemdata = item.data();
eprintln!("itemdata: {:p} = {:?}", itemdata, itemdata);
}
我不明白我在做什么错。为什么编译器不生成警告?是否去除了载体的(非复制)项目?是一生的模棱两可吗?
答案 0 :(得分:4)
如何返回对全局向量或内部Option的引用?
impl Entity {
pub fn data(&self) -> &Data {
self.modifier.as_ref().unwrap_or_else(|| &DATA[self.idata])
}
}
但是它生成了错误的指令,并且程序因
SIGILL
崩溃
您问题中的代码在具有Rust 1.27.2或1.28.0的macOS上没有此行为。在Ubuntu上,我在Valgrind中运行程序时遇到问题,但是在Rust 1.28.0中问题消失了。
另请参阅: