[解決済み] 実行時に変数の型を取得したい
質問
実行時に変数の型を取得したいのですが、どうすればよいですか? どうすればよいですか?
どのように解決するのですか?
つまり、厳密に言えば、"変数の型"は常に存在し、型パラメータとして渡すことができるのです。例えば
val x = 5
def f[T](v: T) = v
f(x) // T is Int, the type of x
しかし 何をしたいのか する というのは、何の役にも立ちません。例えば、変数の型が何であるかは知りたくないかもしれませんが 値 は、このように、ある特定の型である。
val x: Any = 5
def f[T](v: T) = v match {
case _: Int => "Int"
case _: String => "String"
case _ => "Unknown"
}
f(x)
ここでは、変数の型は関係ありません。
Any
. 重要なのは、チェックされるのは
5
であり、その値である。実際には
T
は意味がありません。
def f(v: Any)
の代わりに また、これは
ClassTag
または値の
Class
であるかどうかを調べることができます。
List[_]
(
List
の)かどうかではなく、例えば、何かの
List[Int]
または
List[String]
.
もう一つの可能性は
リファイ
という変数があります。つまり、型を値に変換して、それを保存したり、渡したりすることができるようにしたいのです。これにはリフレクションが含まれ、次のいずれかを使用します。
ClassTag
または
TypeTag
. 例えば、以下のようになります。
val x: Any = 5
import scala.reflect.ClassTag
def f[T](v: T)(implicit ev: ClassTag[T]) = ev.toString
f(x) // returns the string "Any"
A
ClassTag
で受け取った型パラメータを使用することもできます。
match
. これはうまくいきません。
def f[A, B](a: A, b: B) = a match {
case _: B => "A is a B"
case _ => "A is not a B"
}
でも、これなら
val x = 'c'
val y = 5
val z: Any = 5
import scala.reflect.ClassTag
def f[A, B: ClassTag](a: A, b: B) = a match {
case _: B => "A is a B"
case _ => "A is not a B"
}
f(x, y) // A (Char) is not a B (Int)
f(x, z) // A (Char) is a B (Any)
ここでは
コンテキストバウンズ
の構文があります。
B : ClassTag
の暗黙のパラメータと同じように動作します。
ClassTag
の例では、無名変数が使用されています。
を取得することもできます。
ClassTag
から、値の
Class
のような、このような。
val x: Any = 5
val y = 5
import scala.reflect.ClassTag
def f(a: Any, b: Any) = {
val B = ClassTag(b.getClass)
ClassTag(a.getClass) match {
case B => "a is the same class as b"
case _ => "a is not the same class as b"
}
}
f(x, y) == f(y, x) // true, a is the same class as b
A
ClassTag
は、ベースクラスのみを対象とし、その型パラメータは対象外という制限があります。つまり
ClassTag
に対して
List[Int]
と
List[String]
は同じです。
List
. 型パラメータが必要な場合は
TypeTag
の代わりに A
TypeTag
しかし、これは値から取得することはできず、また、JVMの
消去
.
を使った例
TypeTag
2つのタイプタグを比較することさえも、以下のように単純ではありません。
import scala.reflect.runtime.universe.TypeTag
def f[A, B](a: A, b: B)(implicit evA: TypeTag[A], evB: TypeTag[B]) = evA == evB
type X = Int
val x: X = 5
val y = 5
f(x, y) // false, X is not the same type as Int
もちろん、この比較が真を返すようにする方法はありますが、実際にカバーするには本の数章が必要です。
TypeTag
ということで、この辺でやめておきます。
最後に、変数の型はまったく気にしないという人もいるかもしれません。その場合、答えはとてもシンプルです。
val x = 5
x.getClass // int -- technically, an Int cannot be a class, but Scala fakes it
しかし、何を実現したいのか、もっと具体的に書いた方が、よりポイントを押さえた回答ができるはずです。
関連
-
[解決済み】Spark Exponential Moving Averageについて
-
[解決済み] リフレクションを使用して文字列からプロパティ値を取得する
-
[解決済み] SparkはYarnクラスタ上で動作しています exitCode=13:
-
[解決済み] リフレクションを使ってジェネリックメソッドを呼び出すにはどうしたらいいですか?
-
[解決済み] Javaで汎用配列を作成する方法は?
-
[解決済み] コードが含まれるアセンブリのパスを取得するにはどうすればよいですか?
-
[解決済み] Typeから新しいオブジェクトのインスタンスを作成する方法
-
[解決済み] 変数が定義されているかどうかをチェックする?
-
[解決済み】Type変数を使った変数のキャスティング
-
[解決済み】Scalaのコンテキストとビューバウンドとは何ですか?
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み] Scala underscore - ERROR: 展開された関数のパラメータ型が見つかりません。
-
[解決済み] expr() での lit() の使用について
-
[解決済み] scala 2.11.0 REPL を終了するには?
-
[解決済み] Spark - Sparkでパーセンタイルを計算する方法は?
-
[解決済み] 理解する `andThen`
-
[解決済み] SparkSQL - パーケットファイルを直接読み込む
-
[解決済み】Scalaのvarとvalの定義の違いは何ですか?
-
[解決済み】ScalaのCaseオブジェクトとEnumerationsの比較
-
[解決済み] 型の論理和(ユニオン型)はどのように定義するのですか?
-
[解決済み] sbtのScalaTest:タグなしで単一のテストを実行する方法はありますか?