2015-10-19 60 views
2

我不明白为什么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) } 

我做了使用javapscala -print,找出了以前的代码不能被整理了一些调查没有指定什么i是:

object A { 
    ... 
    def c() = { b((i: Int) => i + 1) } 
} 

为什么会这样呢?有没有其他的方式来重载一个方法,而不是在通话期间指定它的参数的类型?

预先感谢您。

UPDATE

我使用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]),它编译良好。

回答

1

这是因为出于重载解析的目的,参数的输入没有预期的类型,所以没有关于预期什么功能的信息。

http://www.scala-lang.org/files/archive/spec/2.11/06-expressions.html#overloading-resolution

编译器不关心该组可能重载仅包括采取诠释方法。

+0

所以这是以下生成的代码是正确的? 'A.this.b({(new <$ anon:Function1>():Function1)},A $ IntMarker);'(上一个日志的第5行) –

+0

“mean”是什么意思?我不确定-print输出是非常有用的。 –

+0

我不确定要理解你的意思,“参数的输入没有预期类型,所以没有关于预期功能的信息”。你能否提供更多细节?我已阅读上面的链接,但对我来说听起来有点模糊。是关于如何扩展功能? –