質問

The code:

object Link {

  //TYPE-1 (purely functional)
  def apply(name: String, target: Page, f: () => Unit, isExclusive: Boolean) = new Link(name, target, f, isExclusive)
  //..

  //TYPE-2 (purely side-effect)
  def apply(source: Page, target: Page, f: () => Unit, isExclusive: Boolean): Link = {
    val link = Link("LINK [" + source.getName + "]->[" + target.getName + "]", target, f, isExclusive)
    source += link
    link
  }

  //type-2 too
  def apply(source: Page, target: Page, isExclusive: Boolean): Link = Link (source, target, () => Unit, isExclusive)

}

The explanation: there are two types of apply methods - the type-1 simply returns what companion class constructor returns, and the type-2 does not return anything, instead it just does something with the new instance. Thus the two different sets of arguments for them. However, I get the error (see the bottom of the post) on the second type-2 apply method where the _Link_ is marked with the underscores:

  def apply(source: Page, target: Page, isExclusive: Boolean): Link = _Link_ (source, target, () => Unit, isExclusive)

The first type-2 apply method does some job and in the second (and 3rd and 4th...) type-2 apply methods I want to just refer to the first one, instead of duplicating what is written there. However, Scala-IDE does not allow me to do this unless all the apply methods of type-1 are commented out. Seems like that Scala-IDE gets lost among the signatures and can't see my obvious intent. Or am I doing something wrong?

The error: the second apply method shows an error which reads:

overloaded method value apply with alternatives: (source: org.app.Page,target: org.app.Page,f: () => Unit,isExclusive: Boolean)org.app.meta.Link < and> (name: String,target: org.app.Page,f: () => Unit,isExclusive: Boolean)org.app.meta.Link cannot be applied to (org.app.Page, org.app.Page, () => Unit.type, Boolean)

UPDATE

Please note that the type-1 apply method is called without problems from the first type-2 one.

役に立ちましたか?

解決

This is not a bug, check the error message in detail (the interesting part is boldface below) and you will see that the last apply method actually passes a function of wrong type signature, () => Unit.type and not simply () => Unit.

overloaded method value apply with alternatives: (source: org.app.Page,target: org.app.Page,f: () => Unit,isExclusive: Boolean)org.app.meta.Link < and> (name: String,target: org.app.Page,f: () => Unit,isExclusive: Boolean)org.app.meta.Link cannot be applied to (org.app.Page, org.app.Page, () => Unit.type, Boolean)

The reason is that there is only one value of type Unit, namely (), in your case however, when you call () => Unit in the last apply method, you are returning the companion object of type Unit and not its value.

To fix the error your getting, simply replace () => Unit with () => () in your last apply method.

It should then look like this:

def apply(source: Page, target: Page, isExclusive: Boolean): Link = Link (source, target, () => (), isExclusive)

他のヒント

That looks like a bug in the Scala compiler (the error can be reproduced outside of Eclipse using scalac 2.9.2).

Check in the Scala issue tracker if this is a known issue (and open a ticket if needed).

Update

As explained by Harald Meland here, this is not a bug in the compiler.

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top