在工作情况下,类型参数为Set.apply[T]
被推断为A
因为Set[A]
是函数参数的预期类型。
重载解析类型检查参数没有预期的类型,因此编译器不能再使用Set[A]
指导推断您想要什么集合。
这是一个重要的收获the spec http://www.scala-lang.org/files/archive/spec/2.12/06-expressions.html#overloading-resolution,尽管现在它有点被更多有关 SAM 的词语所掩盖。
否则,让 Si... 成为通过键入每个获得的类型列表
论证如下。 [关于函数的一些内容。] 所有其他参数
使用未定义的预期类型键入。
如果它知道一个Set[A]
是预期的,你的集合是这样输入的,而不是作为Set[B]
.
您可以观察打字决策-Ytyper-debug
,它发出的输出有时并不难以理解。
Given
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))
}
此处,值参数的类型为Set[B]
,然后它尝试找到到重载的参数类型的隐式转换,但失败了。
它还寻找一个转换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])