我无法理解为什么Scala无法推断出重载方法的参数:
object A {
implicit object SequenceMarker
implicit object IntMarker
def b(f: Int => Seq[Int])(implicit ev: SequenceMarker.type) = 0
def b(f: Int => Int)(implicit ev: IntMarker.type) = 0
def c() = { b(i => i + 1) } // this doesn't compile
}
当我尝试编译时,我收到以下错误:
error: missing parameter type
def c() = { b(i => i + 1) }
我使用javap
和scala -print
进行了一些调查,并确定在未指定i
的情况下无法编译以前的代码:
object A {
...
def c() = { b((i: Int) => i + 1) }
}
为什么会这样?有没有其他方法来重载方法而不在调用期间指定其参数的类型?
提前谢谢。
更新
我注意到使用scala -print
:
@SerialVersionUID(value = 0) final <synthetic> class anonfun$c$1 extends scala.runtime.AbstractFunction1$mcII$sp with Serializable {
final def apply(i: Int): Int = anonfun$c$1.this.apply$mcII$sp(i);
<specialized> def apply$mcII$sp(i: Int): Int = i.+(1);
final <bridge> <artifact> def apply(v1: Object): Object = scala.Int.box(anonfun$c$1.this.apply(scala.Int.unbox(v1)));
def <init>(): <$anon: Function1> = {
anonfun$c$1.super.<init>();
()
}
}
这个论点似乎是以某种方式进行的:
scala.Int.box(anonfun$c$1.this.apply(scala.Int.unbox(v1)))
此行根据参数的类型而变化:
scala.Int.box(anonfun$c$1.this.apply(scala.Int.unbox(v1)));
...
scala.Int.box(anonfun$c$1.this.apply(v1.$asInstanceOf[String]()))
这可以解释为什么需要这种类型。这是整个日志:
package <empty> {
object A extends Object {
def b(f: Function1, ev: A$SequenceMarker.type): Int = 0;
def b(f: Function1, ev: A$IntMarker.type): Int = 0;
def c(): Int = A.this.b({
(new <$anon: Function1>(): Function1)
}, A$IntMarker);
def <init>(): A.type = {
A.super.<init>();
()
}
};
object A$SequenceMarker extends Object {
def <init>(): A$SequenceMarker.type = {
A$SequenceMarker.super.<init>();
()
}
};
object A$IntMarker extends Object {
def <init>(): A$IntMarker.type = {
A$IntMarker.super.<init>();
()
}
};
@SerialVersionUID(value = 0) final <synthetic> class anonfun$c$1 extends scala.runtime.AbstractFunction1$mcII$sp with Serializable {
final def apply(i: Int): Int = anonfun$c$1.this.apply$mcII$sp(i);
<specialized> def apply$mcII$sp(i: Int): Int = i.+(1);
final <bridge> <artifact> def apply(v1: Object): Object = scala.Int.box(anonfun$c$1.this.apply(scala.Int.unbox(v1)));
def <init>(): <$anon: Function1> = {
anonfun$c$1.super.<init>();
()
}
}
}
因此,我想要实现的目标不能以前面描述的方式完成。还有其他想法吗?
更新2
我也试过了:
def c() = { b(_ + 1) }
但我收到了另一个错误
error: missing parameter type for expanded function ((x$1) => x$1.$plus(1))
def c() = { b(_ + 1) }
当我评论第一个b(f: Int => Seq[Int])
时,它编译得很好。
答案 0 :(得分:1)
这是因为出于重载解析的目的,参数的类型没有预期的类型,因此没有关于预期函数的信息。
http://www.scala-lang.org/files/archive/spec/2.11/06-expressions.html#overloading-resolution
编译器并不关心可能的重载集只包含采用Int的方法。