相关疑难解决方法(0)

编译器建议我添加一个'静态生命周期,因为参数类型可能不够长,但我不认为这是我想要的

我正在尝试实现看起来像这个最小例子的东西:

trait Bar<T> {}

struct Foo<T> {
    data: Vec<Box<Bar<T>>>,
}

impl<T> Foo<T> {
    fn add<U: Bar<T>>(&mut self, x: U) {
        self.data.push(Box::new(x));
    }
}
Run Code Online (Sandbox Code Playgroud)

由于Rust默认为(据我所知)pass-by-ownership,我的心理模型认为这应该有效.该add方法获取对象的所有权,x并且能够将此对象移动到a中,Box因为它知道完整类型U(而不仅仅是特征Bar<T>).一旦进入a Box,框内项目的生命周期应该与框的实际生命周期相关联(例如,当pop()从矢量中删除时,对象将被销毁).

然而,很明显,编译器不同意(我确信比我更了解...),要求我考虑添加一个'static生命周期限定符(E0310).我99%肯定这不是我想要的,但我不确定我应该做什么.

为了澄清我的想法并帮助识别误解,我的心理模型来自C++背景,是:

  • Box<T> 本质上是 std::unique_ptr<T>
  • 如果没有任何注释,则变量按值传递,Copy否则传递rvalue-reference
  • 与参考注释,&大致const&&mut大致&
  • 默认生命周期是词法范围

lifetime rust

36
推荐指数
2
解决办法
5891
查看次数

这个实例如何看似比自己的参数生命周期更长?

在我偶然发现下面的代码之前,我确信类型的生命周期参数中的生命周期总是比其自己的实例更长.换句话说,给定一个foo: Foo<'a>,那么'a总是会活得更久foo.然后我被@Luc Danton(游乐场)介绍给这个反辩论代码:

#[derive(Debug)]
struct Foo<'a>(std::marker::PhantomData<fn(&'a ())>);

fn hint<'a, Arg>(_: &'a Arg) -> Foo<'a> {
    Foo(std::marker::PhantomData)
}

fn check<'a>(_: &Foo<'a>, _: &'a ()) {}

fn main() {
    let outlived = ();
    let foo;

    {
        let shortlived = ();
        foo = hint(&shortlived);
        // error: `shortlived` does not live long enough
        //check(&foo, &shortlived);
    }

    check(&foo, &outlived);
}
Run Code Online (Sandbox Code Playgroud)

尽管foo创建者hint似乎认为生命周期与其自身一样长,并且对它的引用被传递给更广泛范围内的函数,但代码完全按原样编译.取消注释代码中声明的行会触发编译错误.或者,更改Foo为struct tuple (PhantomData<&'a ()>)也会使代码不再使用相同类型的错误进行编译(Playground).

如何有效的Rust代码?这里编译器的原因是什么?

lifetime rust

23
推荐指数
2
解决办法
1906
查看次数

我们如何编写用于检查Serde序列化和反序列化的通用函数?

在涉及自定义Serde(1.0)序列化和反序列化方法的项目中,我依靠此测试例程来检查序列化对象和返回是否会产生等效对象.

// let o: T = ...;
let buf: Vec<u8> = to_vec(&o).unwrap();
let o2: T = from_slice(&buf).unwrap();
assert_eq!(o, o2);
Run Code Online (Sandbox Code Playgroud)

这样的内联工作非常好.我对可重用性的下一步是check_serde为此目的发挥作用.

pub fn check_serde<T>(o: T)
where
    T: Debug + PartialEq<T> + Serialize + DeserializeOwned,
{
    let buf: Vec<u8> = to_vec(&o).unwrap();
    let o2: T = from_slice(&buf).unwrap();
    assert_eq!(o, o2);
}
Run Code Online (Sandbox Code Playgroud)

这适用于拥有类型,但不适用于具有生命周期边界的类型(Playground):

check_serde(5);
check_serde(vec![1, 2, 5]);
check_serde("five".to_string());
check_serde("wait"); // [E0279]
Run Code Online (Sandbox Code Playgroud)

错误:

error[E0279]: the requirement `for<'de> 'de : ` is not satisfied (`expected bound lifetime parameter 'de, found concrete lifetime`)
  --> …
Run Code Online (Sandbox Code Playgroud)

serialization lifetime rust serde

12
推荐指数
1
解决办法
625
查看次数

标签 统计

lifetime ×3

rust ×3

serde ×1

serialization ×1