【问题标题】:How to resolve ambiguous method reference in scala如何解决scala中不明确的方法引用
【发布时间】:2015-09-02 21:27:35
【问题描述】:

这是我遇到的具体问题。我用的是SLF4J Logger (下面是变量logger的类型)

//After adding to a map
logger debug ("Adding {} = {}", key, value)

这是鼠标悬停在 Eclipse(和编译器)中告诉我的内容。

对重载定义的模糊引用,在 (x$1: String, x$2: Object*) 类型的 trait Logger 中进行方法调试和在 (x$1: String, x$2: Any, x 类型的 trait Logger 中进行方法调试$3: Any)单位匹配参数类型(字符串、字符串、字符串)

我明白他们为什么模棱两可。我当然不是在与编译器争论:)。我只想知道经验丰富的程序员是如何解决这个问题的。

以下是我可以使用的替代方法

  1. 创建和数组,并使用 Object* 定义

    logger debug ("Adding {} = {}", Array(key, value):_*)

  2. 投射到Any

    logger debug ("Adding {} = {}", key.asInstanceOf[Any], value.asInstanceOf[Any])

这两种方法都不是特别吸引人。社区对我有更好的方法或建议吗?

非常感谢!

【问题讨论】:

  • 看起来这可能是一个已知问题 - 请参阅 here
  • 我想就是这样。感谢您的帮助@Shadowlands!如果您可以将其发布为答案,我可以将问题标记为已解决,我们可以帮助社区。​​span>
  • 通过字符串插值,我总是使用logger debug (s"Adding $key = $value)这些数据。由于字符串插值是编译时间,它可能也更有效
  • @ArneClaassen 对不起我的无知。但是你的代码中的“s”是什么?
  • Scala 2.10 添加了字符串插值。 "s" 和其他类似的解释在这里:docs.scala-lang.org/overviews/core/string-interpolation.html

标签: scala slf4j


【解决方案1】:

我会用

logger.debug("Adding {} = {}", key, value: Any)

也可以使用以下选项:

logger.debug("Adding {} = {}", Array(key, value):_*)

请关注:_*。如果您省略这些符号,它将调用 Object* 方法,仅提供 1 个参数,该参数将是一个数组。

【讨论】:

  • 是的,@OlegRudenko 您指出错误是正确的。我没有正确输入。我猜当我写 Object* 时,我一定在心里检查过 _* 。无论如何,错误就是错误。感谢您纠正它。我会更正我原来的问题。
  • 似乎第一种方法比第二种方法更可取,即使日志级别被禁用,第二种方法也会创建一个数组。也许将该版本包装在启用调试的检查中?
  • 使用 Scala 日志记录。 :) 答案只是为了展示如何解决模棱两可的方法引用。关于性能:我的经验表明,您应该专注于代码的可读性,只有在您真正看到需要时才优化性能。
【解决方案2】:

首先要感谢@Shadowlands、@ArneClaassen 和@OlgeRudenko。 如 cmets 所述,这似乎是已知问题。这阻止了我试图“解决”它。接下来要做的是找到一个不会破坏 Scala 习语的好方法。

考虑到这些限制,我选择使用上面建议的字符串插值。我也切换到scala-logging。引用他们的 GitHub/README,

Scala Logging 是一个封装 SLF4J 的便捷且高性能的日志库。这很方便,因为您可以简单地调用日志方法而无需检查是否启用了相应的日志级别:

logger.debug(s"Some $expensive message!")

它是高性能的,因为多亏了 Scala 宏,才应用了 check-enabled-idiom,就像编写这个更复杂的代码一样:

if (logger.isDebugEnabled) logger.debug(s"Some $expensive message!")

谢谢大家!就我而言,这已经解决了。如果评论员可以发布他们的答案,我将很乐意承认他们。

一如既往,站在友好巨人的肩膀上感觉很好!

PS:我刚刚验证了字符串插值没有执行成本如果您使用 scala-logging。我的验证方法很粗糙但很有效。

    log.debug{ 
        {
          throw new IllegalAccessException("This should not have been called with debug off!")
        }
        s"Added Header ${name}:${headerValue}"
      }

果然,当我将我的日志设置为DEBUG 时,抛出异常,正如预期的那样,但当我将其设置为更高级别时它消失了。 是的,我已经删除了IllegalAccessException 部分:)。

【讨论】:

  • 谢谢!我忘了提。我已切换到 scala 日志记录。除非 debug 为真,否则调试语句没有执行成本。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-07
  • 2014-04-02
相关资源
最近更新 更多