Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/rust/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Rust 链接拥有或引用的事物序列_Rust_Lifetime - Fatal编程技术网

Rust 链接拥有或引用的事物序列

Rust 链接拥有或引用的事物序列,rust,lifetime,Rust,Lifetime,我试图让事物具有一种特性,既可以简单地包含其他事物,也可以根据需要根据事物的名称创建它们。这些包含的东西反过来也应该能够做同样的事情,创建一个排序层次结构。下面是一个最小的代码: use std::ops::Deref; pub enum BoxOrRef<'a, T: ?Sized + 'a> { Boxed(Box<T>), Ref(&'a T), } impl<'a, T: ?Sized + 'a> Deref for Box

我试图让事物具有一种特性,既可以简单地包含其他事物,也可以根据需要根据事物的名称创建它们。这些包含的东西反过来也应该能够做同样的事情,创建一个排序层次结构。下面是一个最小的代码:

use std::ops::Deref;

pub enum BoxOrRef<'a, T: ?Sized + 'a> {
    Boxed(Box<T>),
    Ref(&'a T),
}

impl<'a, T: ?Sized + 'a> Deref for BoxOrRef<'a, T> {
    type Target = T;
    fn deref(&self) -> &T {
        match self {
            BoxOrRef::Boxed(b) => &b,
            BoxOrRef::Ref(r) => r,
        }
    }
}

pub trait Elem {
    fn get_subelem<'a, 'b>(&'a self, name: &'b str) -> Option<BoxOrRef<'a, dyn Elem>>;
}

pub trait Table {
    fn get_elem<'a, 'b>(&'a self, name: &'b str) -> Option<BoxOrRef<'a, dyn Elem>>;
}

fn resolve_name<'a, T: Table + ?Sized>(
    table: &'a T,
    name: &[String],
) -> Option<BoxOrRef<'a, dyn Elem>> {
    let mut segments = name.iter();
    if let Some(first_segment) = segments.next() {
        segments.fold(table.get_elem(&first_segment), |res, next| {
            res.and_then(|elem| elem.get_subelem(next))
        })
    } else {
        None
    }
}
使用std::ops::Deref;
pub enum BoxOrRef{
盒装,
参考号(&'T),
}
为BoxOrRef>执行命令;
}
pub特征表{
fn获取元素(&'a self,name:&'b str)->选项(
表:&'T,
名称:&[String],
)->选项src/lib.rs:26:17
|

26 | fn resolve_nameget_subelem
的返回值不能超过您过去调用它的
&self
,因为
get_subelem
的签名明确表示:

fn get_subelem<'a, 'b>(&'a self, name: &'b str) -> Option<BoxOrRef<'a, dyn Elem>>;
//                      ^^                                         ^^
一旦您将生存期参数添加到所有
Elem
中,上述更改将使您的示例编译,但在实现
Elem
时,这将使您处于尴尬的境地:您无法返回对
self
的引用,因此实际上所有内容都必须装箱


考虑到示例的模糊性,很难给出一个好的建议,但我建议您后退一步,考虑一下
BoxOrRef
是否是这里正确的抽象。从根本上说,您不能使用
BoxOrRef
做任何您不能使用引用的事情,因为
BoxOrRef
可能是一个引用e、 同时,你不能用它做任何你不能用
盒子
做的事情,因为它可能是一个
盒子
。使用
ToOwned
实现
克隆
到你拥有的
——也许类似的方法也适用于你。(如果可以的话,可以为
dyn Elem
实现
ToOwned
,并直接使用
Cow
。)

我不确定这有多大帮助,但代码可以进一步简化。我还不明白为什么这适用于
&
ref,而不适用于自定义
ref
包装器。@PeterHall问题在于
deref
(或任何类型的访问器方法)与
Ref
vs
&
::不同。如果在我的示例中注释掉
()
,您将得到相同的错误。如果注释掉
()
'a
,则错误消失。
pub trait Elem<'a> {
    fn get_subelem(&self, name: &str) -> Option<BoxOrRef<'a, dyn Elem<'a>>>;
}