【问题标题】:Is there a way to obtain the location and file name of where a value is initialized in Rust?有没有办法获取在 Rust 中初始化值的位置和文件名?
【发布时间】:2021-07-07 08:18:37
【问题描述】:

有没有办法获取在 Rust 中初始化值的位置和文件名?我知道file!line! 宏,但它们提供了它们最初被调用的位置的信息,我希望从值的初始化位置确定这些信息。比如下面的代码不起作用,但和我想要的差不多:

// Contains a value as well as where this value was initialized
struct Foo {
    value : usize,
    file : String,
    line : u32,
}
impl Foo {
    fn new(value : usize) -> Foo {
        Foo {
            value,
            file : String::from(std::file!()),
            line : std::line!(),
        }
    }
}

// Test the result
fn main() {
    let foo1 = Foo::new(0);
    println!("foo1 created in file \"{}\" line {}",foo1.file,foo1.line);
    let foo2 = Foo::new(1);
    println!("foo2 created in file \"{}\" line {}",foo2.file,foo2.line);
}

返回

foo1 created in file "src/main.rs" line 12
foo2 created in file "src/main.rs" line 12

其中不包含创建值的正确行号。我也在尝试尽可能透明地执行此操作,以便用户无需为创建的每个值输入宏。至于为什么,我试图在代码中插入一些调试信息,这将有助于用户了解该值是在代码中的哪个位置创建的。

【问题讨论】:

  • 我认为这是不可能的,除非您定义自己的过程宏(即使那样它也很不确定,因为很难在其他 crate 中找到类型并由宏定义)。你需要这个功能做什么?当执行恐慌时,它应该出现在问题区域以帮助用户找到问题。如果您定义了一个单独的函数来执行恐慌,您可能需要考虑将其转换为宏。
  • 它用于调试,问题是恐慌会给出恐慌的位置,而不是实例化值的位置。我在看一个自动区分代码。在代码中,一个值可能是可微分的,但它并不重要,除非用户要求该值的导数。例如,abs(0) 给出了一个有效值,但它不可微。因此,在派生处理期间会引发恐慌,但随后用户不知道问题发生在代码中的哪个位置。他们只会知道导数处理的位置,这没什么帮助
  • 我不确定我是否完全理解你,但听起来你想显示错误发生在被区分的函数的哪个位置,而不是在代码中的哪个位置被定义。我想这会更容易通过返回Err(x) 而不是恐慌来实现,这样当错误沿调用堆栈向上传播时,可以将周围的上下文添加到x。然后,一旦用户解开错误,您就可以使用自定义的Debug 实现来突出显示存在问题的部分。
  • 是的,我认为有一个误解。我需要原始值实例化发生的位置。尝试这个。想象一个代码,我们在其中创建了一组表示为树的排序值。我们从一个空集开始,然后使用语法set.insert(x) 添加新值。现在,我们可以添加任何值,这不是错误。然而,如果我们调用set.process(),如果集合包含任何,比如零,我们想抛出一个错误。在那个错误中,我们想知道set.insert(0) 发生在哪里,但并不真正关心set.process() 发生在哪里。正常的恐慌或错误会给出后者。我想要前者。

标签: rust


【解决方案1】:

您可以通过使用#[track_caller] 属性标记函数并使用std::panic::Location::caller() 而不是file!()line!() 宏来做到这一点。这最初是为打印恐慌的位置而设计的,但似乎并不局限于这种情况。

Playground

【讨论】:

    猜你喜欢
    • 2020-12-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-09-18
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多