gpt4 book ai didi

Scala 在编译时获取函数调用的行和文件

转载 作者:行者123 更新时间:2023-12-04 06:28:40 25 4
gpt4 key购买 nike

我想要的是一个能够从它被调用的地方打印行+文件的函数。

行为将是这样的:

log("x") //Called at line 15 of file Blax.scala

应该打印
Blax.scala, line 15, message: x

类似于以下 C++ 代码的东西:
    void _log(const char* message, const char* file, int line) { std::cout << file << ", " << line << ", message: " <<
message
<< "\n";}
#define log(message) _log(message, __FILE__, __LINE__)

这可以在 Scala 中做到吗?是否有可能以一种半可读且与 future 和旧版本的编译器兼容的方式来完成?

我一直在尝试基于这里的宏部分实现类似的东西: https://docs.scala-lang.org/overviews/macros/overview.html

但是代码非常难以阅读,而且这些文章似乎没有涵盖与我需要的内容密切相关的任何内容。

我想我的问题可以分为两三个:

a) 是否可以通过像函数一样调用宏来在 Scala 中内联任何类型的“传统”代码?

所以基本上打电话 blax(a)扩展为 impl_blax(a, "b", __C__)编译前。

b) 在 Scala 编译时获取当前行号和文件名的“推荐”方式是什么?

c) 如果 a 或 b 是不可能的,还有没有办法完成我想要的?

澄清:

是的,使用 Stack 跟踪很容易做到这一点,但是抛出异常并获取 Stack 跟踪的速度慢得难以忍受,并且除了某些特定的调试情况外不适合任何其他情况。我正在寻找一种无开销或低开销的解决方案,因此我要求使用宏

编辑(为了回答标志):

@Seth Tisue 关于将问题标记为重复的问题

如果您将此标记为重复的问题解决了我的问题,我很想听听如何。原始问题中的一些链接导致 404,最高投票答案的代码(未标记为正确)似乎没有做任何与我想要的相关的事情,并且其中的一部分在 Scala 2.12 中被标记为已弃用。 .. 我确实偶然发现了这个问题,但我希望更明确地说明这个问题可能会产生一个以前链接 4 岁的问题所没有的答案。

最佳答案

除非您想将此作为练习并因此推出您自己的解决方案,否则我会说推荐的方法是重用现有的、经过测试并满足您的要求的库。

我找到了两个候选人:

1. 源代码

sourcecode库基于宏并在编译时提供元数据。

示例(取自根据您的问题调整的页面):

object Main extends App {
def log(message: String)(implicit line: sourcecode.Line, file: sourcecode.File) =
println(s"${file.value}, line ${line.value}, message: $message")

log("x")
}

这将打印:

/Users/jhoffmann/Development/sourcecode/src/main/scala/Main.scala, line 5, message: x



2. Scala 日志

作为标准的替代方案,只需使用普通的旧日志记录即可。看看 scala-logging .使用 logback作为后端,您可以使用 %file , %line%message在你的模式中。

例如,考虑在 logback.xml 中配置的以下模式:
<pattern>%file, line %line, message: %message%n</pattern>

然后这段代码:
object Main extends App with LazyLogging {
logger.info("x")
}

将打印:

Main.scala, line 4, message: x

关于Scala 在编译时获取函数调用的行和文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47012688/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com