在我正在开发的 crate 中,我有几个unsafe函数,由于explained in this answer原因而被标记为此类。在unsafe函数中,我可以执行unsafe操作,就像将完整的函数主体包装在unsafe { }块中一样。

问题在于,在较大的函数中,函数主体中只有一小部分实际上在执行unsafe操作,而其余部分则在做非常安全的事情。通常,这种安全的东西甚至完全独立于unsafe代码。在这些较大的函数中,我想缩小unsafe操作的范围。原因应该是可以理解的:我也不会因为可以而将完整的代码库包装在unsafe { }块中。

不幸的是,没有safe { }块可以“反转” unsafe函数的行为。如果有的话,我会这样使用它:

unsafe fn my_function() {
    safe {
        // ... doing safe stuff ...

        unsafe {
            // ... doing `unsafe` stuff ...
        }

        // ... doing safe stuff ...
    }
}

但这是不可能的:在这些情况下缩小unsafe操作范围的最佳实践是什么?有解决这个问题的技巧吗?

只是要清楚一点:这个问题不是在讨论缩小unsafe范围是好是坏。我说过我想这样做:这个问题是关于如何做以及实际中最常用的解决方案(如果有)。 (而且,如果您不明白我为什么要这样做,this RFC是非常相关的。)

最佳答案

如果要将unsafe关键字用作对所有不安全操作进行分类的方法,则可以通过将代码拆分为安全的私有(private)函数来构造更准确的边界。我不确定它是否完全符合您的“最佳实践”要求,因为我不知道使用该技术的任何大型项目,但可以使用:

// Document the assumptions of this unsafe function here
pub unsafe fn my_function() {
    my_internal_function()
}

// private
fn my_internal_function() {
    // ... doing safe stuff ...
    unsafe {
        // Document the assumptions of this unsafe block here
        // ... doing `unsafe` stuff ...
    }
    // ... doing safe stuff ...
}

如果您担心实际上存在一个不安全使用的“安全”功能,并存在意外使用不当的风险,则可以嵌套这些私有(private)功能,以便在主要不安全功能之外无法调用它们:
pub unsafe fn my_function() {
    fn my_internal_function() {
        // ... doing safe stuff ...
        unsafe {
            // Document the assumptions of this unsafe block here
            // ... doing `unsafe` stuff ...
        }
        // ... doing safe stuff ...
    }

    my_internal_function();
}

在完成所有这些操作之后,正确注释不正确的代码假设是正确的最重要部分。仅当您担心不安全行数的度量标准时,这种技巧才有用。

关于rust - 对于 `unsafe`函数的最佳实践是什么,其中只有一小部分代码实际上在做 `unsafe`事情?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/57522200/

10-11 07:00