当方法以看似无关的方式重载时,为什么scala无法编译?
class A {} class B extends A {} object Sample { def foo(a: Set[A]) { println("Hi Set[A]") } // def foo(a: String) { // println("Hi A") // } } Sample.foo(Set(new B())) 上面的代码与scala愉快地运行.但是,当我取消注释foo(a:String)时,代码无法编译: test.scala:13: error: overloaded method value foo with alternatives: (a: String)Unit <and> (a: Set[this.A])Unit cannot be applied to (scala.collection.immutable.Set[this.B]) Sample.foo(Set(new B())) ^ one error found foo(a:String)似乎与尝试使用Set [B]调用foo无关.到底是怎么回事? 编辑: 让我感到困惑的不仅仅是为什么未注释的版本不能编译,而是为什么它会在foo(a:String)被注释掉时进行编译.通过添加方法foo(a:String)我改变了什么? 设置为不变量并不能解释当foo(a:String)被注释掉时成功编译的原因. 解决方法
在工作的情况下,Set.apply [T]的类型参数被推断为A,因为Set [A]是函数参数的预期类型.
重载决策类型检查没有预期类型的??参数,因此编译器不能再使用Set [A]来指导您想要的集合的推断. 这是the spec的一个重要收获,尽管现在有更多关于SAM的言论埋没了.
如果它知道预期有一个Set [A],那么你的集合就是这样输入的,而不是Set [B]. 您可以使用-Ytyper-debug观察输入决策,它会发出有时不易察觉的输出. 特定 class A ; class B extends A object X { def f(as: Set[A]) = ??? ; def f(s: String) = ??? } object Main extends App { X.f(Set(new B)) } 这里,value参数被输入为Set [B],然后它尝试并且无法找到对重载的param类型的隐式转换. 它还寻找将X对象转换为带有F方法的类型,该方法采用Set [B]. | |-- X.f(Set(new B())) BYVALmode-EXPRmode (site: value <local Main> in Main) | | |-- X.f BYVALmode-EXPRmode-FUNmode-POLYmode (silent: value <local Main> in Main) | | | |-- X EXPRmode-POLYmode-QUALmode (silent: value <local Main> in Main) | | | | -> X.type | | | -> (s: String)Nothing <and> (as: Set[A])Nothing | | |-- Set(new B()) BYVALmode-EXPRmode (silent: value <local Main> in Main) | | | |-- Set BYVALmode-EXPRmode-FUNmode-POLYmode (silent: value <local Main> in Main) | | | | |-- scala.Predef.Set.apply BYVALmode-EXPRmode-FUNmode-POLYmode (silent: value <local Main> in Main) | | | | | [adapt] [A](elems: A*)CC[A] adapted to [A](elems: A*)CC[A] | | | | | -> (elems: A*)scala.collection.immutable.Set[A] | | | | [adapt] => scala.collection.immutable.Set.type adapted to [A](elems: A*)CC[A] | | | | -> (elems: A*)scala.collection.immutable.Set[A] | | | |-- new B() BYVALmode-EXPRmode-POLYmode (silent: value <local Main> in Main) | | | | |-- new B BYVALmode-EXPRmode-FUNmode-POLYmode (silent: value <local Main> in Main) | | | | | |-- new B EXPRmode-POLYmode-QUALmode (silent: value <local Main> in Main) | | | | | | |-- B FUNmode-TYPEmode (silent: value <local Main> in Main) | | | | | | | -> B | | | | | | -> B | | | | | -> ()B | | | | -> B | | | solving for (A: ?A) | | | -> scala.collection.immutable.Set[B] | | [search #1] start `(s: String)Nothing <and> (as: Set[A])Nothing`,searching for adaptation to pt=scala.collection.immutable.Set[B] => String (silent: value <local Main> in Main) implicits disabled | | 15 implicits in companion scope | | [search #2] start `(s: String)Nothing <and> (as: Set[A])Nothing`,searching for adaptation to pt=(=> scala.collection.immutable.Set[B]) => String (silent: value <local Main> in Main) implicits disabled | | 15 implicits in companion scope | | [search #3] start `(s: String)Nothing <and> (as: Set[A])Nothing`,searching for adaptation to pt=scala.collection.immutable.Set[B] => Set[A] (silent: value <local Main> in Main) implicits disabled | | 15 implicits in companion scope | | [search #4] start `(s: String)Nothing <and> (as: Set[A])Nothing`,searching for adaptation to pt=(=> scala.collection.immutable.Set[B]) => Set[A] (silent: value <local Main> in Main) implicits disabled | | 15 implicits in companion scope | | second try: <error> and Set(new B()) | | |-- Set(new B()) EXPRmode (silent: value <local Main> in Main) | | | |-- Set BYVALmode-EXPRmode-FUNmode-POLYmode (silent: value <local Main> in Main) | | | | |-- scala.Predef.Set.apply BYVALmode-EXPRmode-FUNmode-POLYmode (silent: value <local Main> in Main) | | | | | [adapt] [A](elems: A*)CC[A] adapted to [A](elems: A*)CC[A] | | | | | -> (elems: A*)scala.collection.immutable.Set[A] | | | | [adapt] => scala.collection.immutable.Set.type adapted to [A](elems: A*)CC[A] | | | | -> (elems: A*)scala.collection.immutable.Set[A] | | | solving for (A: ?A) | | | -> scala.collection.immutable.Set[B] | | [search #5] start `X.type`,searching for adaptation to pt=X.type => ?{def f(x$1: ? >: scala.collection.immutable.Set[B]): ?} (silent: value <local Main> in Main) implicits disabled | | [search #6] start `X.type`,searching for adaptation to pt=(=> X.type) => ?{def f(x$1: ? >: scala.collection.immutable.Set[B]): ?} (silent: value <local Main> in Main) implicits disabled badset.scala:7: error: overloaded method value f with alternatives: (s: String)Nothing <and> (as: Set[A])Nothing cannot be applied to (scala.collection.immutable.Set[B]) (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |