如何返回对全局向量或内部Option的引用?

时间:2018-08-20 19:32:19

标签: rust

我正在尝试创建一种方法,该方法可以返回对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);
}

Complete code

我不明白我在做什么错。为什么编译器不生成警告?是否去除了载体的(非复制)项目?是一生的模棱两可吗?

1 个答案:

答案 0 :(得分:4)

  

如何返回对全局向量或内部Option的引用?

通过使用Option::unwrap_or_else

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中问题消失了。

另请参阅: