相关疑难解决方法(0)

为什么我不能在同一个结构中存储值和对该值的引用?

我有一个值,我想在我自己的类型中存储该值以及对该值内部内容的引用:

struct Thing {
    count: u32,
}

struct Combined<'a>(Thing, &'a u32);

fn make_combined<'a>() -> Combined<'a> {
    let thing = Thing { count: 42 };

    Combined(thing, &thing.count)
}
Run Code Online (Sandbox Code Playgroud)

有时候,我有一个值,我想在同一个结构中存储该值和对该值的引用:

struct Combined<'a>(Thing, &'a Thing);

fn make_combined<'a>() -> Combined<'a> {
    let thing = Thing::new();

    Combined(thing, &thing)
}
Run Code Online (Sandbox Code Playgroud)

有时,我甚至没有参考该值,我得到同样的错误:

struct Combined<'a>(Parent, Child<'a>);

fn make_combined<'a>() -> Combined<'a> {
    let parent = Parent::new();
    let child = parent.child();

    Combined(parent, child)
}
Run Code Online (Sandbox Code Playgroud)

在每种情况下,我都会收到一个错误,即其中一个值"活不够长".这个错误是什么意思?

lifetime rust borrow-checker

193
推荐指数
3
解决办法
2万
查看次数

强制删除struct字段的顺序

我正在实现一个对象,该对象拥有通过FFI从C库创建的多个资源.为了清理构造函数恐慌时已经完成的工作,我将每个资源包装在自己的结构中并Drop为它们实现.但是,当涉及到删除对象本身时,我不能保证资源将以安全的顺序被删除,因为Rust没有定义结构字段被删除的顺序.

通常情况下,您可以通过设置它来解决这个问题,因此对象不拥有资源,而是借用它们(以便资源可以相互借用).实际上,这会将问题推到调用代码中,其中drop order被很好地定义并且使用借用的语义来强制执行.但这对我的用例来说是不合适的,而且一般来说还是有点狡猾.

令人气愤的是,如果因为某些原因而drop采取这种做法,这将非常容易.然后我可以按照我想要的顺序打电话.self&mut selfstd::mem::drop

有没有办法做到这一点?如果没有,是否有任何方法可以在构造函数出现紧急情况时进行清理而无需手动捕获和重新计算?

raii rust

10
推荐指数
1
解决办法
872
查看次数

在范围内拥有不正确(大于正确)生命周期的引用是否可以?

&'a T如果'a引用值大于引用值,引用是否会立即导致 UB(未定义行为)?或者,只要不超过 type 的引用值,就可以拥有这样的引用T吗?

作为比较:mem::transmute::<u8, bool>(2)是直接 UB,即使您从未访问过返回值。如果您有一个带有 value 的引用,情况也是如此0,因为引用必须始终有效。即使您从未访问过它们。另一方面,在ptr::null()您尝试取消引用空指针之前,拥有不是问题。

考虑这个代码:

let x = '';
let r_correct: &char = &x;

{
    let r_incorrect: &'static char = unsafe { mem::transmute(r_correct) };
    println!("{}", r_incorrect);
}
Run Code Online (Sandbox Code Playgroud)

在这段代码中,有两个对x. 都活不下去了x。但这种类型r_incorrect显然是谎言,因为x不会永远活着。

这段代码是否表现出明确定义的行为?我看到三个选项:

  • (a) 此代码表现出未定义的行为。
  • (b) 此代码的行为定义明确(“安全”)。
  • (c) Rust 还没有定义关于这部分语言的规则。

unsafe lifetime rust

6
推荐指数
2
解决办法
234
查看次数

标签 统计

rust ×3

lifetime ×2

borrow-checker ×1

raii ×1

unsafe ×1