[Scala]入門 型パラメータと暗黙の引数
以下の連載の8,9回目読んだ。
http://www.atmarkit.co.jp/ait/kw/scala.html
型パラメータ
準備
class Base class Hoge extends Base class Piyo extends Hoge class Fuga
上限境界
Javaでいう<Foo extends Base>
Scalaの慣習として、型パラメータはAから始めるらしい。
class Foo[A <: Base] new Foo[Hoge] //Baseを継承していないのでエラー //new Foo[Fuga]
クラス定義☆
特定のクラス定義を持つクラスを指定できる。
ダックタイピングっぽい?面白そう。
class Foo[A <: {def hoge():Unit}] class Bar{ def hoge = println } new Foo[Bar]
抽象型
抽象クラス、抽象メソッドに加え、フィールドや型も抽象化できる。
いまいち使いどころが分からない。
abstract class Base{ type SomeFoo //抽象型 def show(foo:SomeFoo) } class Foo{ def exec = println("Exec") } class Child extends Base{ type SomeFoo = Foo //抽象型をFooに def show(foo:SomeFoo) = foo.exec }
型パラメータと同じ型境界の設定ができる。
この例だと最初からFoo型にしておけばいい気がするが…
type someFoo <: Foo //someFoo extends Foo扱い
暗黙の型変換
implicitで型変換メソッドを指定すると勝手に呼んでくれる
implicit def intToString(i:Int):String = i.toString() val str:String = 1
なお、stringToIntを定義すると、ambiguous(曖昧)と言われてエラーになる。
しかし val i:Int = "1" で暗黙的な型変換が行われるわけでもない。謎。
Note that implicit conversions are not applicable because they are ambiguous
標準クラスを自作クラスへと変換したいときに使う?valueOfの代わり?
暗黙の引数
引数の型に合わせた値をあらかじめ用意しておくと、デフォルト値のように働く。
使いどころが分からない。適当に使うと危険に思える。
def hoge(implicit str:String) = println(str) //暗黙の引数がないのでエラー //hoge() implicit val hogege = "hoge" hoge //暗黙の引数を利用。hoge()だとコンパイルエラー hoge("piyo") //普通にも呼べる
可視境界
A <: Hogeの暗黙の型変換対応版。
暗黙の型変換でAとみなせるならOK
class X[A <% Hoge]
関数の呼び出し制約
型パラメータによって、インスタンス化はできるが、特定の関数呼び出しを禁止する
class X[A]{ def exec(implicit arg:A =:= Int) = println("exec") } val intx = new X[Int] val strx = new X[String] intx.exec //コンパイルエラー //strx.exex
上限境界extendsを表したいなら以下。AはIntを継承したもの。
def exec(implicit A <:< Int)