Scala 为什么提取和分配单个元组值会导致递归隐式搜索?
以下是产生此错误的代码:Scala 为什么提取和分配单个元组值会导致递归隐式搜索?,scala,implicits,Scala,Implicits,以下是产生此错误的代码: [info] Compiling 1 Scala source to /tmp/test/target/scala-2.11/classes... [error] /tmp/test/test.scala:4: recursive value x$1 needs type [error] final implicit val (enc, dec) = { [error] ^ [error] one error fo
[info] Compiling 1 Scala source to /tmp/test/target/scala-2.11/classes...
[error] /tmp/test/test.scala:4: recursive value x$1 needs type
[error] final implicit val (enc, dec) = {
[error] ^
[error] one error found
build.sbt
斯卡拉测试
试图编译此文件将导致以下错误:
[info] Compiling 1 Scala source to /tmp/test/target/scala-2.11/classes...
[error] /tmp/test/test.scala:4: recursive value x$1 needs type
[error] final implicit val (enc, dec) = {
[error] ^
[error] one error found
在完全调试模式打开的情况下,我可以看到它正在尝试解析==
,编译器正在查看当前隐式,以确定是否有匹配项。由于(enc,dec)
是隐式的,它似乎也使用它们,因此它尝试键入它们,导致编译器抱怨这种隐式递归
| | | | | |-- "x".$eq$eq$eq("y") EXPRmode-POLYmode-QUALmode (silent: value x$1 in package)
| | | | | | |-- "x".$eq$eq$eq BYVALmode-EXPRmode-FUNmode-POLYmode (silent: value x$1 in package)
| | | | | | | |-- "x" EXPRmode-POLYmode-QUALmode (silent: value x$1 in package)
| | | | | | | | \-> String("x")
| | | | | | | |-- x$1._1 EXPRmode (site: value enc in package)
| | | | | | | | |-- x$1 EXPRmode-POLYmode-QUALmode (site: value enc in package)
| | | | | | | | | caught scala.reflect.internal.Symbols$CyclicReference: illegal cyclic reference involving value x$1: while typing x$1
[error] /tmp/test/test.scala:4: recursive value x$1 needs type
[error] final implicit val (enc, dec) = {
[error] ^
| | | | | | | | | \-> <error>
| | | | | | | | \-> <error>
| | | | | | | |-- x$1._2 EXPRmode (site: value dec in package)
| | | | | | | | |-- x$1 EXPRmode-POLYmode-QUALmode (site: value dec in package)
| | | | | | | | | \-> <error>
| | | | | | | | \-> <error>
| | | | | | | |-- SafeEquals BYVALmode-EXPRmode-FUNmode-POLYmode (silent: value x$1 in package) implicits disabled
| | | | | | | | |-- ai.x.safe.`package` EXPRmode-POLYmode-QUALmode (silent: value x$1 in package) implicits disabled
| | | | | | | | | \-> ai.x.safe.type
| | | | | | | | \-> ai.x.safe.SafeEquals.type <and> [T](l: T)ai.x.safe.SafeEquals[T]
| | | | | | | solving for (T: ?T)
| | | | | | | solving for (T: ?T)
| | | | | | | solving for (T: ?T)
| | | | | | | [adapt] SafeEquals adapted to [T](l: T)ai.x.safe.package.SafeEquals[T] based on pt String("x") => ?{def ===: ?}
| | | | | | | |-- [T](l: T)ai.x.safe.package.SafeEquals[T] EXPRmode-POLYmode-QUALmode (silent: value x$1 in package)
| | | | | | | | \-> ai.x.safe.package.SafeEquals[String]
| | | | | | | |-- ai.x.safe.`package`.SafeEquals[String]("x").$eq$eq$eq BYVALmode-EXPRmode-FUNmode-POLYmode (silent: value x$1 in package)
| | | | | | | | \-> (r: String)Boolean
| | | | | | | \-> (r: String)Boolean
| | | | | | |-- "y" : pt=String BYVALmode-EXPRmode (silent: value x$1 in package)
| | | | | | | \-> String("y")
| | | | | | \-> Boolean
由于在定义{}
的主体时隐式不存在,因此当从SafeEquals
定位===
可以应用于字符串并使代码工作时,隐式不会干扰编译器的隐式搜索。现在我对这一点没有什么问题,因为它确实有意义,因为可以定义懒惰的递归序列化程序和其他隐式的东西,它们可以毫无问题地使用它们自己。因此,编译器当然应该查看隐式的,它被定义为一个可能的应用程序,以使某些东西工作
但对我来说,奇怪的是,如果在赋值过程中不直接提取元组,这种方法是有效的:
final implicit val tuple = {
("x" === "y") -> 0
}
显然,这不是我想要做的,因为我希望元组中的两个东西都是隐式的(在我的真实案例中,它是来自circe的编码器/解码器对)。但对我来说很奇怪的是,对Tuple2使用提取器(我认为是提取器)会导致搜索隐式的编译器错误。有谁能告诉我为什么会发生这种情况,或者是什么导致了这种行为?我想知道更多关于调试输出中看到的内容。为什么解析元组中每个单独事物的类型会导致编译器错误,但解析整个元组的类型不会导致任何问题?如果将显式类型添加到enc
和dec
,会发生什么情况val(enc:Boolean,dec:Int)=……
@BobDalgleish如果我显式地在元组中键入元素,那么它会编译。我对编译它不太感兴趣,但更感兴趣的是为什么这会导致问题。既然它可以键入整个元组(并因此键入其中的内容)似乎有些奇怪,那么为什么提取单个值会导致错误呢
final val (x,y) = {
("x" === "y") -> 0
}
implicit val (f,b) = (x,y)
final implicit val tuple = {
("x" === "y") -> 0
}