Scala の implicit がいまいちよくわかってなかったけど Android の Listener を小綺麗にかけたらちょっとたのしかったけど黒魔術っぽい話

Scala には謎が多い。その一つが implicit だと思う。

他の言語でもあまりみないキーワードだし、検索するとどういう書き方をするかとか、散発的な使い方は書いてあるけど、今一歩よくわからない。ので調べたら Android というか Listener パターンで使うとわりと良さそうなことがわかった。

implicit の3用法

implicit には使い方が3種類ある。らしい。

  1. 暗黙の型変換
  2. 暗黙の引数
  3. 暗黙のクラス変換?

今回ポイントになるのは 1. の暗黙の型変換 で、2. と 3. は出てきません。というか使わないほうがいいんじゃないかコレ、という感じなので…

暗黙の引数に関しては Scala の implicit parameter は型クラスの一種とはどういうことなのか がすごくわかりやすくてよかったけれど、正直使いこなせる気がしない。

なので、限定的な使い方だけをしようということで、Android で死ぬほど出てくる Listener パターンを implicit でちょっとだけきれいに書きます。

implicit による暗黙の型変換

まず、implicit による型変換。ある型があるべきところに別の型があった場合、普通に考えればコンパイル時にエラーになる。けれど、スコープ内で implicit な型変換

(今ある型) => あるべき型

が定義してあった場合、変換してくれるのでコンパイルが通る。

具体例:

implicit def int2String(int: Int) = int.toString // 戻り値の型は型推論される
val hoge = 125.length

hoge: Int = 3

本来 Int には length メソッドは実装されていないが、implicit な型変換 int2String が定義されているため、length が呼べるべき String に変換されて length が呼べるようになっている。

はい完全に意味不明でなんでこんな悪魔的なものが実装されたのか謎なんだけど、Java  との差分、関数リテラルとかを Java と共存させる場合に効果を発揮する。

Listener パターンにおける無名クラスの関数リテラルによる置き換え

Android では OnClickListener をめちゃめちゃ書くと思う。そこで implicit が使える。
Scala+Android初めて勉強会 を参考にした。わかめさん(@vvakame)が教えてくれたとのこと?

implicit def func2OnClickListener(f: () => Unit) = {
  new OnClickListener {
    override def onClick(v: View) = f() // ()をつけないとちゃんと動作しない
  }
}

view.setOnClickListener(() =>
  // onClick コールバックの実装
)

毎度まいど無名クラスに一つだけのメソッド実装を書くところを、関数リテラルで書ける。ものすごく便利、というわけではないけど、Java と Scala の界面をつなぐにはよいように見える。

黒魔術っぽい

便利は便利なんだけど、いかんせんコードが読みづらくなるし、多用すると確実にアレなことになると思う。

ただ、コレをやってみて思ったのが、implicit が出現するのがあるべき型がその場所にないとき、ということがわかった(超当たり前のことを言っています)のでよかった。

おしまい。

広告

Scala の implicit がいまいちよくわかってなかったけど Android の Listener を小綺麗にかけたらちょっとたのしかったけど黒魔術っぽい話」への2件のフィードバック

コメントを残す

以下に詳細を記入するか、アイコンをクリックしてログインしてください。

WordPress.com ロゴ

WordPress.com アカウントを使ってコメントしています。 ログアウト / 変更 )

Twitter 画像

Twitter アカウントを使ってコメントしています。 ログアウト / 変更 )

Facebook の写真

Facebook アカウントを使ってコメントしています。 ログアウト / 変更 )

Google+ フォト

Google+ アカウントを使ってコメントしています。 ログアウト / 変更 )

%s と連携中