2015-10-19 87 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

我不確定要理解你的意思,「參數的輸入沒有預期類型,所以沒有關於預期功能的信息」。你能否提供更多細節?我已閱讀上面的鏈接,但對我來說聽起來有點模糊。是關於如何擴展功能? –