在类体中隐式提供构造函数params

时间:2014-05-06 14:13:39

标签: scala implicit

我想在类体中隐式提供我的类的显式构造函数参数。

我可以将第二个和后续参数标记为" implicit val",这有效:

scala> class Foo(x: Int, implicit val y: String) {
     |   println(implicitly[String])
     | }
defined class Foo

scala> new Foo(1,"hello")
hello

但如果我将第一个参数标记为implicit,那么Scala认为我将整个参数列表标记为隐式参数列表,并添加一个空的第一个参数列表:

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")
              ^

有没有办法在范围内明确地创建第一个显式构造函数参数?

3 个答案:

答案 0 :(得分:1)

我会说,添加其他本地修饰符:

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")
              ^

从语法上讲,这与前导implicit关键字不同,所以它可能是一个解析器错误,或者它确实将隐式参数列表与本地隐式标记的前导参数区分开来但不使用差异。< / p>

答案 1 :(得分:1)

您可以使用内部implicit def隐式提供该内容:

class Foo(val x: Int, implicit val y: String) {
    implicit def ix = x
}

这是非常冗长的,但看起来似乎还有另一种方法可以解决标记隐式参数列表的implicit和标记隐式字段的implicit val之间的歧义。

答案 2 :(得分:1)

class Foo(x: Int, y: String) {
  implicit val xImp = x

  println(implicitly[Int])
}

实际上,对于第一种情况,我也会这样做。在这种情况下,我认为更容易理解的代码值得更加冗长:

class Foo(x: Int, y: String) {
  implicit val yImp = y

  println(implicitly[String])
}