2016-03-26 5 views
0

入力が4つの整数のタプルである場合にのみタプル値を計算する関数があります。Scalaで警告メッセージ「型の可変型引数Intがチェックされていません」が削除されました

def add(v:Any) = { 
    if (v.isInstanceOf[(Int, Int, Int, Int)]) { 
     val v2 = v.asInstanceOf[(Int, Int, Int, Int)] 
     println(v2._1 + v2._2 + v2._3 + v2._4) 
    } else { 
     println("NOP") 
    } 
} 

object Main extends App { 
    add((1,1,1,1)) 
    add((1,2)) 
} 

Main.main(args) 

これは機能していますが、「非可変型引数...は未チェック」という警告が表示されます。

warning: non-variable type argument Int in type (Int, Int, Int, Int) is 
unchecked since it is eliminated by erasure 
if (v.isInstanceOf[(Int, Int, Int, Int)]) { 

なぜこのエラー、およびどのようなこの警告メッセージを削除するための最良の方法かもしれませんか?

答えて

1

あなたが実際に引数が4つのInt Sのタプルで、これを行うための正しい方法は、各コンポーネントをチェックすることであることを確認する必要がある場合:

def add(v: Any) = v match { 
    case (i1: Int, i2: Int, i3: Int, i4: Int) => 
    println(i1 + i2 + i3 + i4) 
    case _ => 
    println("NOP") 
} 
1

これは、あなたがTypeTagによってそれを解決することができ、コンパイル時にtype erasureによって引き起こされる:

import scala.reflect.runtime.universe._ 
def add[T](v:T)(implicit t: TypeTag[T]) = { 
    if (t.tpe =:= typeOf[(Int, Int, Int, Int)]) { 
     val v2 = v.asInstanceOf[(Int, Int, Int, Int)] 
     println(v2._1 + v2._2 + v2._3 + v2._4) 
    } else { 
     println("NOP") 
    } 
} 
+0

これは、実際に必要な動作はありません、それは引数の_static_型が '(Int、Int、Int、Int)'の場合にのみ動作します。例えば。 'Any'を返す関数の戻り値で呼び出された場合は動作しません。 –

1

あなたはパターンマッチングでinstanceOf Sを交換した場合@unchecked

def add(v: Any) = v match { 
    case t: (Int, Int, Int, Int) @unchecked => 
    println(t._1 + t._2 + t._3 + t._4) 
    case _ => 
    println("NOP") 
} 

で警告を抑制することができますあなたがClassCastException

を得る Tuple4を渡すではない (Int, Int, Int, Int)を渡す

タプルのジェネリック型は型の削除により削除されるため、コンパイラはこれが実行時に動作することを保証できません。Tuple4が渡された場合にのみ表示されます。関数が(Int, Int, Int, Int)Tuple4以外で呼び出されます、そして、あなたはTypeTag Sを進めるべきであることも可能であるならば、私が提示

ソリューションは、トラブルの原因となり、それだけでそんなにきれいに見えると反射を必要としないotherways 。

+0

これはよりクリーンでより慣用的なので、これはより良い選択です。 – Crembo

関連する問題