rust 如何使用`unsafe`创建多个引用?

798qvoo8  于 2023-10-20  发布在  其他
关注(0)|答案(2)|浏览(134)

我尝试使用unsafe来防止防火墙检查器阻塞安全的东西。但是,unsafe块似乎没有任何效果。
下面是一个重现该问题的示例代码:

struct Element {
    pub data: usize,
}

unsafe fn recursiveFunction(element: &Element, elements: &mut Vec<Element>) {
    elements.push(Element {
        data: element.data + 1,
    });
    let index = elements.len() - 1;
    if elements.last().unwrap().data > 100 {
        return;
    }
    unsafe {
        recursiveFunction(&elements[index], elements);
    }
}

在这里,我仍然得到错误“cannot borrow *elements as mutable because it is also borrowed as immutable”。我知道element永远不会指向无效数据。

h5qlskok

h5qlskok1#

你要做的是创建一个共享的和一个 * 独占的 * 引用,这是不可能的,Rust中的引用 * 必须 * 遵守llvms指针别名规则,或者你调用undefined behavior
但是你的函数很容易用安全的Rust编写,你可以只传递索引而不是引用:

fn recursive_function(idx: usize, elements: &mut Vec<Element>) {
    elements.push(Element {
        data: elements[idx].data + 1,
    });
    let index = elements.len() - 1;
    if elements.last().unwrap().data > 100 {
        return;
    }
    recursive_function(index, elements);
}

但是你调用的初始元素也必须在向量内部。我们可以通过创建一个小的 Package 器来缓解这个问题:

fn wrapper(element: &Element, elements: &mut Vec<Element>) {
    elements.push(Element {
        data: element.data + 1,
    });
    recursive_function(elements.len() - 1, elements)
}

它可以被称为像原始的recursiveFunction

wnrlj8wa

wnrlj8wa2#

出现问题的原因是您希望在函数调用中的两个参数中使用相同的变量,这可以通过创建element的新示例(或在本例中为克隆)来从elements数组中引用此元素来修复。
另一方面,unsafe块并不像你想象的那样工作,unsafe块是用来做不安全的事情的,也就是说,Rust在内存管理中失去控制的事情(比如当你有一个可变的静态变量时),如book中所示。

#[derive(Clone)]
struct Element {
    pub data: usize,
}

fn recursiveFunction(element: &Element, elements: &mut Vec<Element>) {
    elements.push(Element { data: element.data + 1 });
    let index = elements.len() - 1;
    if elements.last().unwrap().data > 100 {
        return;
    }
    let element = elements[index].clone();
    recursiveFunction(&element, elements);
}

相关问题