【问题标题】:Converting Java to Scala durations将 Java 转换为 Scala 持续时间
【发布时间】:2015-11-11 14:53:14
【问题描述】:

有没有优雅的方式将java.time.Duration 转换为scala.concurrent.duration.FiniteDuration

我正在尝试在 Scala 中对 Config 进行以下简单使用:

val d = ConfigFactory.load().getDuration("application.someTimeout")

但是我没有看到在 Scala 中使用结果的任何简单方法。 当然希望 Typesafe 的好人没想到我会这样做:

FiniteDuration(d.getNano, TimeUnit.NANOSECONDS)

编辑:请注意该行有一个错误,这证明了这一点。请参阅下面的选定答案。

【问题讨论】:

  • 显示的解决方案有什么问题?这很容易理解。如果它对您来说不够短,请将其包装在一个函数中/创建一个隐式转换。
  • @sschaef 令人烦恼的一点是所谓的“对 scala 友好”的库,用于输出 Java 类型,但在谈到 Config 时,这并不是什么新鲜事。
  • Typesafe Config 根据其项目定义同时服务于 Java 和 Scala 客户端。我同意必须使用隐式转换有点令人惊讶。我在 MyConfig 单例中介绍了这一点,因此应用程序代码永远不需要知道。不应在应用程序级代码中散布原始的 Typesafe Config 访问。
  • 对于某些用途,以特定单位(通常是 ms)读取配置可能就足够了。然后简单的“.toMillis”就可以了。这仍然允许配置文件提供任何对我们人类有益的单元。

标签: scala config duration scala-java-interop


【解决方案1】:

我不知道显式转换是否是唯一的方法,但如果你想做正确的事

FiniteDuration(d.toNanos, TimeUnit.NANOSECONDS)

toNanos 会返回总持续时间,而getNano 只会返回纳秒部分,这不是你想要的。

例如

import java.time.Duration
import jata.time.temporal.ChronoUnit
Duration.of(1, ChronoUnit.HOURS).getNano // 0
Duration.of(1, ChronoUnit.HOURS).toNanos  // 3600000000000L

话虽如此,您也可以滚动自己的隐式转换

implicit def asFiniteDuration(d: java.time.Duration) =
  scala.concurrent.duration.Duration.fromNanos(d.toNanos)

当你在范围内时:

val d: FiniteDuration = ConfigFactory.load().getDuration("application.someTimeout")

【讨论】:

    【解决方案2】:

    scala-java8-compat中有一个函数

    在 build.sbt 中

    libraryDependencies += "org.scala-lang.modules" %% "scala-java8-compat" % "0.9.0"
    
    import scala.compat.java8.DurationConverters._
    
    val javaDuration: java.time.Duration = ???
    val scalaDuration: FiniteDuration = javaDuration.toScala
    

    【讨论】:

      【解决方案3】:

      Scala 2.13开始,有一个专用的DurationConverter从java的Duration到scala的FiniteDuration(反之亦然):

      import scala.jdk.DurationConverters._
      
      // val javaDuration = java.time.Duration.ofNanos(123456)
      javaDuration.toScala
      // scala.concurrent.duration.FiniteDuration = 123456 nanoseconds
      

      【讨论】:

        【解决方案4】:

        我不知道有什么更好的方法,但你可以缩短一点:

        Duration.fromNanos(d.toNanos)
        

        并自己将其包装成隐式转换

        implicit def toFiniteDuration(d: java.time.Duration): FiniteDuration = Duration.fromNanos(d.toNanos)
        

        (将d.toNano更改为d.toNanos

        【讨论】:

          猜你喜欢
          • 2020-09-05
          • 2012-01-29
          • 1970-01-01
          • 2016-11-05
          • 1970-01-01
          • 1970-01-01
          • 2021-07-21
          • 1970-01-01
          • 2012-01-05
          相关资源
          最近更新 更多