每次调用函数时如何访问函数的调用位置?

tim*_*ree 2 debugging rust

我想编写一个函数来访问它被调用的位置的文件和行号。

它看起来像这样:

fn main() {
    prints_calling_location(); // would print `called from line: 2`
    prints_calling_location(); // would print `called from line: 3`
}

fn prints_calling_location() {
    let caller_line_number = /* ??? */;
    println!("called from line: {}", caller_line_number);
}
Run Code Online (Sandbox Code Playgroud)

tim*_*ree 6

RFC 2091:隐式调用者位置添加了track_caller使函数能够访问其调用者位置的功能。

简短回答:要获取调用函数的位置,请在其主体中对其进行标记#[track_caller]和使用std::panic::Location::caller

根据该答案,您的示例将如下所示:

#![feature(track_caller)]

fn main() {
    prints_calling_location(); // would print `called from line: 2`
    prints_calling_location(); // would print `called from line: 3`
}

#[track_caller]
fn prints_calling_location() {
    let caller_location = std::panic::Location::caller();
    let caller_line_number = caller_location.line();
    println!("called from line: {}", caller_line_number);
}
Run Code Online (Sandbox Code Playgroud)

游乐场链接

更具体地说,该函数std::panic::Location::caller有两种行为:

  • 在标记为 的函数中#[track_caller],它返回一个&'static Location<'static>,您可以使用它来找出调用函数的文件、行号和列号。
  • 在没有 的函数中#[track_caller],它具有容易出错的行为,即返回调用它的实际位置,而不是调用函数的位置,例如:

    #![feature(track_caller)]
    
    fn main() {
        oops();
        // ^ prints `line: 10` instead of the expected `line: 4`
    }
    
    // note: missing #[track_caller] here
    fn oops() {
        println!("line: {}", std::panic::Location::caller().line());
    }
    
    Run Code Online (Sandbox Code Playgroud)

    游乐场链接