gpt4 book ai didi

rust - 从条件分配引用的终身问题

转载 作者:行者123 更新时间:2023-12-02 18:15:05 25 4
gpt4 key购买 nike

我对 Rust 很陌生,我遇到了生命周期的问题,我相信我可以理解发生了什么以及为什么,但我无法解决我该如何解决它。

为了简单起见,我创建了这个我实际上想做的事情的简短“克隆”,但真正的代码是使用 asyc-stripe 。如果相关的话,将用真实的代码注释示例代码。

有以下结构:

// https://github.com/arlyon/async-stripe/blob/9f1a84144a23cc7b2124a1252ee15dc646ce0215/src/resources/generated/subscription.rs#L385
struct ObjectA<'a> {
field: i32,
object_b_id: Option<&'a str>,
}

// https://github.com/arlyon/async-stripe/blob/9f1a84144a23cc7b2124a1252ee15dc646ce0215/src/resources/generated/subscription.rs#L570
impl<'a> ObjectA<'a> {
fn new(field: i32) -> Self {
return Self {
field,
object_b_id: Default::default(),
};
}
}

// https://github.com/arlyon/async-stripe/blob/9f1a84144a23cc7b2124a1252ee15dc646ce0215/src/resources/generated/subscription.rs#L210
fn persist_obj_a(obj_a: ObjectA<'_>) {}

// ---

// https://github.com/arlyon/async-stripe/blob/9f1a84144a23cc7b2124a1252ee15dc646ce0215/src/resources/generated/payment_method.rs#L18
struct ObjectB {
id: ObjectBId,
}

// https://github.com/arlyon/async-stripe/blob/9f1a84144a23cc7b2124a1252ee15dc646ce0215/src/ids.rs#L518
struct ObjectBId {
value: String,
}

impl ObjectBId {
fn as_str(&self) -> &str {
return self.value.as_str();
}
}

// This is a wrapper around https://github.com/arlyon/async-stripe/blob/9f1a84144a23cc7b2124a1252ee15dc646ce0215/src/resources/generated/payment_method.rs#L128 that just returns the first one found (id any, hence the Option)
fn load_object_b() -> Option<ObjectB> {
return Some(ObjectB {
id: ObjectBId {
value: String::from("some_id"),
},
});
}

我想要做的是:使用 load_object_b 加载 ObjectB 并将其 ID 使用到 ObjectA 中。

好的,接下来是我的尝试。

第一次尝试

fn first_try(condition: bool) {
let mut obj_a = ObjectA::new(1);

if condition {
match load_object_b() {
Some(obj_b) => obj_a.object_b_id = Some(obj_b.id.as_str()),
None => (),
}
}

persist_obj_a(obj_a);
}

在这里我得到了

obj_b.id does not live long enough

我可以理解,因为据我所知,obj_b仅存在于比赛臂期间,并在比赛结束时被丢弃。

第二次尝试

fn second_try(condition: bool) {
let mut obj_a = ObjectA::new(1);

if condition {
let obj_b = load_object_b();
match obj_b {
Some(ref obj_b) => obj_a.object_b_id = Some(obj_b.id.as_str()),
None => (),
}
}

persist_obj_a(obj_a);
}

我在这里得到了

obj_b.0 does not live long enough

我想这仍然是相同的想法,只是在不同的地方。再说一次,根据我的理解,obj_b 现在只存在于 if 条件的范围内。

第三次也是最后一次尝试

我最终“解决”了它:

fn third_try(condition: bool) {
let mut obj_a = ObjectA::new(1);

let obj_b = load_object_b();
let obj_b_id = match obj_b {
Some(ref obj_b) => Some(obj_b.id.as_str()),
None => None,
};

if condition {
obj_a.object_b_id = obj_b_id;
}

persist_obj_a(obj_a);
}

在这里,我将 obj_b 移动到与 obj_a 具有相同的生命周期。所以它解决了我遇到的问题。我对此解决方案的问题是,即使我不会根据条件使用它,我还是觉得对load_object_b执行(可能昂贵的)请求是浪费资源>。不确定我是否遗漏了一些非常明显的东西,或者只是走上了总体错误的方向,但希望能对我可能做错的事情有所了解。

最佳答案

我认为这应该有效:

fn third_try(condition: bool) {
let mut obj_a = ObjectA::new(1);

let obj_b = if condition { load_object_b() } else { None };
obj_a.object_b_id = obj_b.as_ref().map (|o| o.id.as_str());

persist_obj_a(obj_a);
}

关于rust - 从条件分配引用的终身问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/71690778/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com