2013-12-19 12 views
10

私は可変個の引数を取る関数を持っています。最初は文字列、残りは数値(IntまたはDouble)ですので、引数を取得するためにAny *を使用しています。数字をDoublesとして一様に扱いたいのですが、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/SI1448私たちはまだそれを修正する方向を確信しています。 – gzm0

答えて

4

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) 
+1

最後に '' List'](http://www.scala-lang.org/api/current/index.html#scala.collection.immutable.List)で 'sum'メソッドを使うことができます部分、すなわち: 'nums.sum' – ggreiner

+1

' List'valの名前が大好きです。 –

+0

新しいスカラーです。ケース・ステートメントが意味することを誰かが説明できますか? Intのように、それをintにしますか?私はどのようにnumがListになったかを知ることはできません[Double] mongrelからList [Any] – 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 

マッチングは、それを行うための別の方法についてhereを参照して、Scalaで少しトリッキーであることが判明しました。

1

ちょっと戻って、Any*の代わりにDouble*の機能を使用する方が簡単でしょうか?

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 
関連する問題