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.
精彩评论