2013-12-19 26 views
10

我有一個接受可變數量參數的函數。首先是一個字符串,其餘的是數字(Int或Double),所以我使用Any *來獲取參數。我想將這些數字統一看作雙精度,但我不能只在數字參數中使用asInstanceOf [Double]。例如:使用asInstanceOf將Any轉換爲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 

有沒有辦法做到這一點? (該功能需要將所有數字相加)。

+0

看看這個問題:https://issues.scala-lang.org/browse/SI-1448我們現在還不確定我們要修復它的方向。 – gzm0

回答

4

斯卡拉的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) 
+1

我相信你可以在['List'](http://www.scala-lang.org/api/current/index.html#scala.collection.immutable.List)上使用'sum'方法獲得最後一個部分,即:'nums.sum' – ggreiner

+1

喜歡'List' val的名字。 –

+0

Im新的scala。有人可以解釋案件陳述的意思嗎?就像它的Int類型一樣......讓它成爲Int?我沒有得到如何數量成爲一個名單[雙]從雜種這是一個列表[任何] – user3376961

2

當有需要處理不同類型的,你應該避免鑄造他們,而是使用模式匹配。要添加的所有雙的和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

3

這裏是蘭德爾的回答略有簡化:

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中的一個小技巧,看here做它的另一種方式。

1

退一步,功能可能更容易取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