【问题标题】:Possible to prevent access to a variable declared in the scope or as a function argument?可以防止访问在作用域中声明的变量或作为函数参数吗?
【发布时间】:2017-01-08 21:38:57
【问题描述】:

假设我们有一个变量(在用于其预期目的之后)应该永远被访问。

(就 Rust 而言,这样做可能是有效的,但其内容在应用程序上下文中逻辑上不再有效)。

例如,在 Python 中,您可以简单地这样做:

del myvar;

有没有办法禁止将来访问函数体中声明的变量或作为参数传递的引用?


请注意,通常可以为此使用范围,但这不适用于函数参数。

【问题讨论】:

    标签: scope namespaces rust


    【解决方案1】:

    有一个丑陋的解决方法甚至适用于Copy 值:Shadowing。

    enum Void {}
    
    fn foo(x: i32) -> whatever {
        println!("{}", x);
    
        let x: Void;
        // Now `x` refers to an uninitialized variable with which you
        // couldn't do anything even if it was initialized
    }
    

    但是,错误消息非常可怕,其意图也很不明确。我强烈敦促你重新考虑是否需要这种能力。作为记录,我从未在 Python 代码中看到明确的 del 用于此目的。我也没有在我读过的任何其他代码中回忆起这样的事情。

    【讨论】:

    • 它在 Python 中对于 1) 是自然串行且不保证被拆分为多个函数的函数很有用。 2) 定义要明确结束可能访问(或意外访问)的临时变量。检查 CPython 的代码显示它用于核心模块,例如 osfunctoolsdatetimepdbxml.etree
    • 它会起作用,但你对丑陋的看法是对的——我什至称它为反模式。并且,在函数作用域结束后停止工作。
    【解决方案2】:

    您可以将它传递给使用其参数的任何函数(只要您在要执行此操作的范围内拥有它的所有权)。一个例子是drop,它确实(和only)做到了这一点。之后任何尝试使用它都会导致“移动后使用”错误。

    foo 作为要删除参数s 的块的简单示例:

    fn foo(s: String) -> whatever {
        println!("{}", s);
    
        drop(s); // fn drop<T>(_x: T) { }
    
        println!("{}", s); // error: use of moved value: `s` [E0382]
    
        // do stuff
    }
    

    请注意,这仅适用于未实现 Copy 的类型。

    编辑:我想我找到了Copyable 类型的解决方案;他们可以是Boxed,之后他们可以是dropped:

    let x = Box::new(5);
    println!("{}", x); // ok
    
    drop(x);
    
    println!("{}", x); // error: use of moved value
    

    【讨论】:

    • 如问题中所述,这不适用于函数参数。
    • @ideasman42:当然可以。 fn f(s: String) { drop(s); /* s is no longer valid */ }.
    • 该评论在问题中的编辑之前和我的答案中的编辑之前:) - 我建议在排除该选项之前先添加一个包装器范围。
    • 这不适用于引用的参数。
    • 不,不是,但这不是条件。我认为引用是不可能的,因为借用对象的全部意义在于它仍然可以在之后使用。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-03-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-11-30
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多