メソッド引数とコンストラクタ引数のimplicitパラメータ
最近ずっとHaskellの話題だったんですが、今日はScalaです。
最近少しずつ仕事でもScalaを使うようになってきて、
勉強しなおしてます。
早速表題の件ですが、
class Hoge(val name:String) class Foo(implicit hoge:Hoge) implicit val hoge = new Hoge("hoge") val foo = new Foo
そもそもこんな事がしたい事がありまして、
いろいろ事情があって、
コンパニオンオブジェクトを作って、
applyメソッドを実装してみよう、という事になりました。
結果、このようなコードを書いてみました。
object Foo { def apply(implicit hoge:Hoge) = new Foo }
これを、こうすると、エラーになりました。
scala> Foo() <console>:12: error: not enough arguments for method apply: (implicit hoge: Hoge)Foo in object Foo. Unspecified value parameter hoge. Foo() ^
うーん、、、newの時は
scala> new Foo res6: Foo = Foo@5b080f38 scala> new Foo() res7: Foo = Foo@ddb1fe0
大丈夫なのに、applyメソッドはダメなの??
と思い、色々試した結果、
object Foo { def apply()(implicit hoge:Hoge) = new Foo }
このようにしたら出来ました。
scala> Foo() res8: Foo = Foo@61e90abf
ちなみに、そもそもFooをcaseクラスにする事でも実現はできました。
scala> case class Foo(implicit hoge:Hoge) defined class Foo scala> Foo() res9: Foo = Foo(Hoge@728edb84)
うーん、コンストラクタとメソッドでimplicitパラメータの仕様が違うのか??
ちょっと試してみました。
scala> def bar(implicit hoge:Hoge) = hoge.name bar: (implicit hoge: Hoge)String scala> bar res10: String = hoge scala> bar() <console>:11: error: not enough arguments for method bar: (implicit hoge: Hoge)String. Unspecified value parameter hoge. bar() ^
なるほど、、、そうなんですね。
でも、これって何故こうなんでしょうか?
続きは明日以降に調べてみます、、、