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()))
Run Code Online (Sandbox Code Playgroud)
上面的代码很愉快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
Run Code Online (Sandbox Code Playgroud)
foo(a: String)似乎它应该与试图foo用一个调用无关Set[B].到底是怎么回事?
编辑:
让我感到困惑的不仅仅是为什么未注释的版本不能编译,而是为什么它在编译时会foo(a: String)被注释掉.我通过添加方法改变了什么foo(a: String)?
Set不变不能解释为何在foo(a: String)注释时成功编译.
在工作情况下,类型参数 toSet.apply[T]被推断为,A因为Set[A]是函数参数的预期类型。
重载解析类型检查参数没有预期的类型,因此编译器不能再用来Set[A]指导推断您想要的集合。
这是规范中的一个重要内容,尽管现在它被有关 SAM 的更多文字所掩盖。
否则,令 Si... 为通过键入每个参数获得的类型列表,如下所示。[关于函数的一些事情。] 所有其他参数都使用未定义的预期类型进行键入。
如果它知道Set[A]需要 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))
}
Run Code Online (Sandbox Code Playgroud)
在这里,值参数的类型为Set[B],然后它尝试找到到重载的参数类型的隐式转换,但失败了。
它还使用采用 的方法查找X对象到类型的转换。fSet[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])
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
716 次 |
| 最近记录: |