Использование asInstanceOf для преобразования Any в Double
У меня есть функция, которая принимает переменное количество аргументов. Первая - это String, а остальные - числа (Int или Double), поэтому я использую Any * для получения аргументов. Я хотел бы рассматривать числа равномерно как Doubles, но я не могу просто использовать asInstanceOf [Double] для числовых аргументов. Например:
val arr = Array("varargs list of numbers", 3, 4.2, 5)
val d = arr(1).asInstanceOf[Double]
дает:
java.lang.ClassCastException: java.lang.Integer cannot be cast to java.lang.Double
Есть ли способ сделать это? (Функция должна содержать все числа).
Ответы
Ответ 1
Scala asInstanceOf
- это его имя для кастинга. Кастинг не преобразуется.
То, что вы хотите, может быть выполнено следующим образом:
val mongrel = List("comment", 1, 4.0f, 9.00d)
val nums = mongrel collect { case i: Int => i case f: Float => f case d: Double => d }
val sumOfNums = nums.foldLeft(0.0) ((sum, num) => sum + num)
Ответ 2
Вот небольшое облегчение ответа Рэндалла:
val mongrel = List("comment", 1, 4.0f, 9.00d)
val nums = mongrel collect { case i: java.lang.Number => i.doubleValue() }
val sumOfNums = nums.sum
Соответствие для любого номера оказывается немного сложным в Scala, см. здесь для другого способа сделать это.
Ответ 3
Когда вам нужно обрабатывать разные типы, вам следует избегать их кастования и вместо этого использовать сопоставление шаблонов. Чтобы добавить все элементы Double и Int в массив, вы можете использовать:
val array = Array("varargs list of numbers", 3, 4.2, 5)
array.foldLeft(0.0){
case (s, i: Int) => s + i
case (s, d: Double) => s + d
case (s, _) => s
}
Соответствие шаблону позволяет вам обрабатывать каждый отдельный тип отдельно и избегать запуска в ClassCastExceptions
.
Ответ 4
Отступив на мгновение, может быть проще, чтобы функция приняла Double*
вместо Any*
?
scala> def foo(str: String, nums: Double*) {
nums foreach { n => println(s"num: $n, class: ${n.getClass}") }
}
foo: (str: String, nums: Double*)Unit
scala> foo("", 1, 2.3)
num: 1.0, class: double
num: 2.3, class: double