开发者

Problems with Scala constructors and enums

I have the following class definition in Scala:

class AppendErrorMessageCommand private(var m_type: Byte) {

  def this() = this(0x00)

  def this(errorType: ErrorType) = this(getErrorTypeValue(errorType))

  private def getErrorTypeValue(errorType: ErrorType) = {
    if(errorType == USER_OFFLINE)
      0x01
    else if(errorType == PM_TO_SELF)
      0x02

    0x00  
  }
}

ErrorType is the following enum:

object ErrorType extends Enumeration {

  type ErrorType = Value
  val USER_OFFLINE, PM_TO_SELF = Value
}

I think something is wrong with the constructor definitions in the class. My IDE (which is the Scala IDE for Eclipse) tells me it cannot find getErrorTypeValue. It also tells me that the overloaded constructor is has alternatives. One being the byte and the other the enum.

Don't take these error messages of the IDE seriously though. They might be wrong, as this often ha开发者_如何学JAVAppens with the IDE. But nonetheless, when the IDE tells me something is wrong, it usually is wrong.

So, what is the problem with my class/constructor definitions?


In this case the IDE is perfectly correct and agrees with the scala command line compiler.

Your constructor takes a Byte, so you need to provide it with one (0x00 is an Int), you need to import ErrorType._ and you need to move getErrorTypeValue to the companion object and declare it to return a Byte (the inferred type is an Int):

object ErrorType extends Enumeration {
  type ErrorType = Value
  val USER_OFFLINE, PM_TO_SELF = Value
}

import ErrorType._

object AppendErrorMessageCommand {
  private def getErrorTypeValue(errorType: ErrorType): Byte = {
    if(errorType == USER_OFFLINE)
      0x01
    else if(errorType == PM_TO_SELF)
      0x02

    0x00  
  }
}

class AppendErrorMessageCommand private(var m_type: Byte) {
  def this() = this(0x00.toByte)
  def this(errorType: ErrorType) = this(AppendErrorMessageCommand.getErrorTypeValue(errorType))
}

Another, better way is to avoid having multiple constructors and use a factory method:

object AppendErrorMessageCommand {
  def apply() = new AppendErrorMessageCommand(0x00)
  def apply(b: Byte) = new AppendErrorMessageCommand(b)
  def apply(errorType: ErrorType) = new AppendErrorMessageCommand(AppendErrorMessageCommand.getErrorTypeValue(errorType))

  private def getErrorTypeValue(errorType: ErrorType): Byte = {
    if(errorType == USER_OFFLINE)
      0x01
    else if(errorType == PM_TO_SELF)
      0x02

    0x00  
  }
}

class AppendErrorMessageCommand private(var m_type: Byte) {
}

See the answers to How can I call a method in auxiliary constructor?


0x00 etc are Int literals that happen to be in hexadecimal.

getErrorTypeValue returns an Int so this(getErrorTypeValue(errorType)) refers to a constructor taking an Int, which doesn't exist.

If you want to type your number literals as Byte, use 0x01: Byte, or specify the return type of your method private def getErrorTypeValue(errorType: ErrorType): Byte = { to use an implicit cast.


The problem is you can't call getErrorTypeValue when delegating the constructor 'cause the object isn't created yet.

I think.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜