Scala 使构造函数参数在类主体中隐式可用

Scala 使构造函数参数在类主体中隐式可用,scala,implicit,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 但是如果我将第一个参数标记为隐式,那么Scala认为我将整个参数列表标

我想使类的显式构造函数参数在类主体中隐式可用

我可以将第二个和后续参数标记为“
implicit val
”,它可以工作:

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

scala> new Foo(1,"hello")
hello
但是如果我将第一个参数标记为
隐式
,那么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")
              ^
scala>类栏(隐式val x:Int,y:String){
|println(隐式[Int])
| }
定义的类栏
scala>新栏(1,“你好”)
:9:错误:构造函数栏()的参数太多(隐式x:Int,隐式y:String)栏
新酒吧(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")
              ^
scala>class Foo(@deprecated(“,”)私有隐式val x:Int,val y:String){println(隐式[Int])
警告:有1个弃用警告;有关详细信息,请使用-deprecation重新运行
定义类Foo
scala>new Foo(42,“你好”)
:9:错误:构造函数Foo:()(隐式x:Int,y:String)Foo的参数太多
新富(42,“你好”)
^

从语法上讲,这与前导的
implicit
关键字不同,因此可能是解析器错误,也可能它确实区分了隐式参数列表和标记为本地隐式的前导参数,但没有使用差异。

您可以通过在内部使用
隐式def
使其隐式可用:

class Foo(val x: Int, implicit val y: String) {
    implicit def ix = x
}
这非常冗长,但似乎没有其他方法可以绕过
implicit
标记隐式参数列表和
implicit val
标记隐式字段之间的歧义

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])
}

谢谢看起来Scala编译器应该能够分辨出两者之间的区别。正如您所指出的,它仍然失败。尽管它们共享关键字
implicit
implicit def
implicit val
是完全不同的动物。
implicit def
是一种转换,当表达式未按写入方式进行类型检查时使用(“因为引用值成员未出现在其应用的实际类型中”)。
implicit val
提供了一个值,该值可以自动传递给采用类型兼容的
implicit
形式参数的方法或构造函数。@RandallSchulz,这是不正确的。不带参数的
隐式定义
隐式val
的作用相同。采用一个参数的
隐式定义
将充当隐式转换。@RandallSchulz从更深层次上讲,隐式转换实际上只是一种隐式转换,根本不是另一种动物。例如,如果您将
Map
标记为隐式,因为它的子类型是
a=>B
,那么您已经提供了隐式转换。啊,的确如此。为了完整性起见,我将注意到2.11编译器根本不会抱怨包含多个参数的
隐式def
。至于单参数
隐式定义
隐式val
或零参数
隐式定义
本质上是同一回事,我不同意,因为触发编译器搜索要使用的参数是完全不同的。谢谢,我同意。我想没有办法做我想做的事。我接受了“翼潜艇”的回答,因为它和你的答案基本相同,他们比你早几秒到达那里。