Reputation: 15448
I would like to make the explicit constructor parameters of my class implicitly available in the class body.
I can mark the second and subsequent parameters as "implicit val
", which works:
scala> class Foo(x: Int, implicit val y: String) {
| println(implicitly[String])
| }
defined class Foo
scala> new Foo(1,"hello")
hello
but if I mark the first parameter as implicit
, then Scala thinks I am marking the whole argument list as an implicit argument list, and adds an empty first argument list:
scala> class Bar(implicit val x: Int, y: String) {
| println(implicitly[Int])
| }
defined class Bar
scala> new Bar(1,"hello")
<console>:9: error: too many arguments for constructor Bar: ()(implicit x: Int, implicit y: String)Bar
new Bar(1,"hello")
^
Is there any way to make the first explicit constructor argument explicitly in scope?
Upvotes: 1
Views: 525
Reputation: 2773
class Foo(x: Int, y: String) {
implicit val xImp = x
println(implicitly[Int])
}
Actually I would do it similarly for the first case too. This is a situation where I think that the lot more understandable code is worth a bit more verbosity:
class Foo(x: Int, y: String) {
implicit val yImp = y
println(implicitly[String])
}
Upvotes: 1
Reputation: 13667
You can make it implicitly available by using an implicit def
inside:
class Foo(val x: Int, implicit val y: String) {
implicit def ix = x
}
which is hideously verbose, but it doesn't look like there is another way to get around the ambiguity between implicit
marking a parameter list implicit and implicit val
marking an implicit field.
Upvotes: 1
Reputation: 39577
I would have said, Add other local modifiers:
scala> class Foo(@deprecated("","") private implicit val x: Int, val y: String) { println(implicitly[Int]) }
warning: there were 1 deprecation warning(s); re-run with -deprecation for details
defined class Foo
scala> new Foo(42, "hi")
<console>:9: error: too many arguments for constructor Foo: ()(implicit x: Int, y: String)Foo
new Foo(42, "hi")
^
Syntactically, that's different from the leading implicit
keyword, so maybe it's a parser bug, or maybe it does distinguish an implicit param list from a leading param marked locally-implicit but doesn't use the difference.
Upvotes: 1