Skip to content

Instantly share code, notes, and snippets.

@choplin
Created September 19, 2012 03:26
Show Gist options
  • Select an option

  • Save choplin/3747493 to your computer and use it in GitHub Desktop.

Select an option

Save choplin/3747493 to your computer and use it in GitHub Desktop.
job.setOutputFormatClass(classOf[TextOutputFormat]) // エラー
job.setOutputFormatClass(classOf[TextOutputFormat[Text, Text]]) // OK
@yuroyoro
Copy link
Copy Markdown

長い型を書くのがタルいんだったらtype aliasを使えばよいと思うマス

scala> trait TextOutputFormat[A,B]
defined trait TextOutputFormat

scala> trait Text
defined trait Text

scala> type TTT = TextOutputFormat[Text,Text]
defined type alias TTT

scala> classOf[TTT]
res3: Class[TTT] = interface TextOutputFormat

genericなclassOfが欲しいなら、こんな感じでユーティリティな関数を用意しておくくらいでしょうか。
2.10だったら、ManifestはdeplicatedになるのでTypeTagやClassTagを使って下さい。

可変長型引数に対応してないので、kindの数に応じてgenClassOf2とか作るしかないです。
多分2.10になってマクロ使えたらもっと綺麗に書ける。

scala> def genClassOf[A[_],B](implicit mf:ClassManifest[A[B]]) = mf.erasure.asInstanceOf[Class[A[B]]]
genClassOf: [A[_], B](implicit mf: ClassManifest[A[B]])Class[A[B]]

scala> genClassOf[List,Int]
res0: Class[List[Int]] = class scala.collection.immutable.List

scala> def genClassOf2[A[_,_],B,C](implicit mf:ClassManifest[A[B,C]]) = mf.erasure.asInstanceOf[Class[A[B,C]]]
genClassOf2: [A[_,_], B, C](implicit mf: ClassManifest[A[B,C]])Class[A[B,C]]

scala> genClassOf2[Map,String,Int]
res1: Class[Map[String,Int]] = interface scala.collection.immutable.Map

scala> genClassOf2[TextOutputFormat,Text,Text]
res2: Class[TextOutputFormat[Text,Text]] = interface TextOutputFormat

ここまで書いて、結局タルいのあんまり解決してないのに気がついた……

@xuwei-k
Copy link
Copy Markdown

xuwei-k commented Sep 19, 2012

そもそも java.lang.Class 型のオブジェクトって以下のようになるので

Welcome to Scala version 2.9.2 (Java HotSpot(TM) 64-Bit Server VM, Java 1.6.0_35).
Type in expressions to have them evaluated.
Type :help for more information.

scala> classOf[Option[Int]]
res0: java.lang.Class[Option[Int]] = class scala.Option

scala> classOf[Option[String]]
res1: java.lang.Class[Option[String]] = class scala.Option

scala> res0 == res1
res2: Boolean = true

classOfに渡す型に型パラメータを渡しても意味がなかった(なので結局 classOf[Option[_]] って書けばいい )気がするんですが、違いましたっけ?

@xuwei-k
Copy link
Copy Markdown

xuwei-k commented Sep 19, 2012

あ、でもとりだそうと思えばできますね

scala> res0.getTypeParameters
res3: Array[java.lang.reflect.TypeVariable[java.lang.Class[Option[Int]]]] = Array(A)

scala> res1.getTypeParameters
res4: Array[java.lang.reflect.TypeVariable[java.lang.Class[Option[String]]]] = Array(A)

ただ、その情報を内部で使ってないなら classOf[Option[_]] とかでいい気がします

@choplin
Copy link
Copy Markdown
Author

choplin commented Sep 19, 2012

job.setOutputFormatClass(classOf[TextOutputFormat[_,_]])

で動いたので内部では型パラメータは使っていないようです。

これでHadoop MRは大分シンプルに書けそうです。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment