来自 String 的 Scala FiniteDuration

Scala FiniteDuration from String

是否可以在不编写自定义代码的情况下在 Scala 中将 String 解析为 FiniteDuration

Duration 上有一个名为 create 的方法,它接受 String,但是会生成 Duration,但不确定如何进一步使用它来从中创建一个 FiniteDurationDuration 上有一些工厂方法可以生成 FiniteDuration 实例,但这些方法意味着我必须解析我的字符串以生成它们的参数(它们的签名需要一个 long 和一个 TimeUnit)。

我提到的这些类型来自scala.concurrent.duration.

谢谢。

您可以使用您提到的方法来创建一个 Duration 对象(或者简单地使用 apply 方法)。然后,您可以通过 collecting 检查它是否是 FiniteDuration(因为 FiniteDurationDuration 的子类型),尽管根据您的使用有多种变体案例:

scala> val finite = Duration("3 seconds")
scala> val infinite = Duration("Inf")
scala> val fd = Some(finite).collect { case d: FiniteDuration => d }
fd: Option[scala.concurrent.duration.FiniteDuration] = Some(3 seconds)
scala> val id = Some(infinite).collect { case d: FiniteDuration => d }
id: Option[scala.concurrent.duration.FiniteDuration] = None

希望对您有所帮助。

使用.toMinutes和类似的函数也是一个简单的解决方案。

FiniteDuration(Duration("48 hours").toMinutes, MINUTES)

完整示例:

scala> import scala.concurrent.duration._
import scala.concurrent.duration._

scala> FiniteDuration(Duration("48 hours").toMinutes, MINUTES)
res0: scala.concurrent.duration.FiniteDuration = 2880 minutes

如果您使用的是 Scala 2.13 或更高版本,您还可以利用 isFinite method on Duration object to get Option[FiniteDuration], with the help of Option.when.

这是一个如何做到这一点的例子:

val dA: Duration = Duration("Inf")
val dB: Duration = Duration("48 hours")

val a = Option.when(dA.isFinite)(dA.asInstanceOf[FiniteDuration])
val b = Option.when(dB.isFinite)(dB.asInstanceOf[FiniteDuration])

println(a) // -> None
println(b) // -> Some(2 days)

然后您还可以编写 implicit conversion,这将帮助您像这样将所有 Duration 转换为 Option[FiniteDuration]...

implicit val durationToFinite: Duration => Option[FiniteDuration] = 
  d => Option.when(d.isFinite)(d.asInstanceOf[FiniteDuration])

val finiteDurationD: Option[FiniteDuration] = Duration("Int")
val finiteDurationE: Option[FiniteDuration] = Duration("48 hours")

println(finiteDurationD) // -> None
println(finiteDurationE) // Some(2 days)