如何将任意数字转换为长整型

12

假设我有:

val number:AnyVal

我知道x可能是任意数字(在我们的情况下,是浮点数、双精度数、整数或长整数)。

将这样的数字转换为长整数最简单的方法是什么:

val l = number.toLong   //fails for AnyVal
4个回答

21

如果你知道它一定是浮点型、双精度型、整数型或长整型,那么你可以将其转换为数字类型。然后,你就可以调用longValue方法:

val number:AnyVal = 10
val l:Long = number.asInstanceOf[Number].longValue

很不错 - 我从来没有想到它可以正确地进行自动装箱 - 绝对是值得记住的东西。 - Ed Staub
但是我们如何更改number的类型? - Akmal Salikhov

13

怎么样:

scala> import scala.util.Try
import scala.util.Try

scala> val i1: Int = 23
i1: Int = 23

scala> val l1: Long = 42
l1: Long = 42

scala> val f1: Float = 14.9f
f1: Float = 14.9

scala> val d1: Double = 14.96
d1: Double = 14.96

scala> val b1: Boolean = true
b1: Boolean = true

scala> List(i1, l1, f1, d1, b1) map (x => Try(x.asInstanceOf[Number].longValue)) foreach (println(_))
Success(23)
Success(42)
Success(14)
Success(14)
Failure(java.lang.ClassCastException: java.lang.Boolean cannot be cast to java.lang.Number)

scala> List(i1, l1, f1, d1, b1) map (x => Try(x.asInstanceOf[Number].longValue)) foreach (n => println(n.get))
23
42
14
14
java.lang.ClassCastException: java.lang.Boolean cannot be cast to java.lang.Number
    at $anonfun$1$$anonfun$apply$1.apply$mcJ$sp(<console>:14)
    at $anonfun$1$$anonfun$apply$1.apply(<console>:14)
    at $anonfun$1$$anonfun$apply$1.apply(<console>:14)
    at scala.util.Try$.apply(Try.scala:161)
    at $anonfun$1.apply(<console>:14)
    at $anonfun$1.apply(<console>:14)
    at scala.collection.TraversableLike$$anonfun$map$1.apply(TraversableLike.scala:244)
    at scala.collection.TraversableLike$$anonfun$map$1.apply(TraversableLike.scala:244)
    at scala.collection.immutable.List.foreach(List.scala:318)
    at scala.collection.TraversableLike$class.map(TraversableLike.scala:244)
    at scala.collection.AbstractTraversable.map(Traversable.scala:105)
    at .<init>(<console>:14)

3

Scala 2.11更新的答案

我的原始回答在Scala的新版本中不再适用,因为对RichLong的隐式转换不再可用。

这个更新的版本通过类型匹配处理数字的子类型,并通过Scala 2.11中的隐式转换来处理字符串:

object LongNumber {
  def cast(number: Any): Long = number match {
    case n: Number => n.longValue()
    case x         => throw new IllegalArgumentException(s"$x is not a number.")
  }

  // Test cases
  def main(args: Array[String]): Unit = {
    val twelveByte:     Byte   = 0x0c
    val twelveString:   String = "12"

    println(s"Converting a long:   ${cast(12L)}")
    println(s"Converting an int:   ${cast(12)}")
    println(s"Converting a double: ${cast(12.0)}")
    println(s"Converting a byte:   ${cast(twelveByte)}")
    println(s"Converting a string: $twelveString")
  }
}

匹配技术是其他答案中使用的投射技术的微小变化。

较早版本Scala的原始答案

在匹配块中尝试将隐式转换为RichLong似乎非常有效:

import scala.runtime.RichLong

...

  def cast(number: Any): Long = number match {
    case n: RichLong => n.toLong
    case x => throw new IllegalArgumentException(s"$x is not a number.")
  }

如果您想考虑这种可能性,也可以添加一个匹配数字格式字符串的情况。


已更新至Scala 2.11。 - richj

1
如果您没有更具体类型的信息,那么您将需要针对每个选项进行模式匹配。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接