在Scala中键入参数vs Any

时间:2016-03-29 19:20:17

标签: scala types any

我有一个类RBase,以及一个继承自它的RInt类。 Base有三个接口函数。由于继承的子类可以使用不同类型的值,因此函数参数的类型为Any。因此,我需要使用asInstanceOf来实现子类。这是一个例子。

abstract class RBase(val name:String)
{
    def encode(value:Any) : Array[Byte]
    def decode(byteArray: Array[Byte]) : Any

    def check(value:Any) : Boolean
}

class RInt extends RBase("int")
{
    override def encode(value: Any) = {
        val byteValue = value.asInstanceOf[Int]
        Array[Byte](byteValue.toByte, byteValue.toByte, byteValue.toByte)
    }
    override def decode(byteArray: Array[Byte]) : Any = {
         byteArray.size   
    }
    override def check(value:Any) : Boolean = {
        val byteValue = value.asInstanceOf[Int]
        if (byteValue.toInt > 0) true
        else false
    }
}


object Main extends App {
    val b = new RInt
    println(b.decode(Array[Byte]()))
    println(b.encode(100).mkString(":"))
    println(b.check(-1))
}

// uncomment when compile
Main.main(args)

我认为可以使用类型参数删除AnyasInstanceOf。这是我的第一次尝试。

abstract class TBase(val name:String)
{
    def encode[T](value:T) : Array[Byte]
    def decode[T](byteArray: Array[Byte]) : T
    def check[T](value:T) : Boolean
}

class TInt extends TBase("bit")
{
    override def encode[Int](value: Int) = {
        Array[Byte](value.toByte, value.toByte, value.toByte)
    }
    override def decode[Int](byteArray: Array[Byte]) : Int = {
         byteArray.size   
    }
    override def check[Int](value:Int) : Boolean = {
        if (value > 0) true
        else false
    }
}

object Main extends App {
    val b = new TInt
    println(b.decode(Array[Byte]()))
}

// uncomment when compile
Main.main(args)

不幸的是,我有以下错误消息。

T.scala:11: error: value toByte is not a member of type parameter Int
        Array[Byte](value.toByte, value.toByte, value.toByte)
                          ^
T.scala:11: error: value toByte is not a member of type parameter Int
        Array[Byte](value.toByte, value.toByte, value.toByte)
                                        ^
T.scala:11: error: value toByte is not a member of type parameter Int
        Array[Byte](value.toByte, value.toByte, value.toByte)
                                                      ^
T.scala:14: error: type mismatch;
 found   : scala.Int
 required: Int(in method decode)
         byteArray.size
                   ^
T.scala:17: error: value > is not a member of type parameter Int
        if (value > 0) true
                  ^
5 errors found
  • Q1:如何改进使用Any和asInstanceOf的RBase方法?
  • Q2:TBase有什么问题?

1 个答案:

答案 0 :(得分:2)

你的想法非常接近。参数化整个类而不是单个方法。

abstract class TBase[T](val name: String) {
  def encode(value: T): Array[Byte]
  def decode(byteArray: Array[Byte]): T
  def check(value: T): Boolean
}

class TInt extends TBase[Int]("bit") {
  override def encode(value: Int) = {
    Array[Byte](value.toByte, value.toByte, value.toByte)
  }
  override def decode(byteArray: Array[Byte]): Int = {
    byteArray.size
  }
  override def check(value: Int): Boolean = {
    if (value > 0) true
    else false
  }
}

编辑:回答为什么你的代码不起作用 - 因为你用一个名为" Int"的类型参数化了方法。编译器认为它只是该类型的名称(它可以是T,U,Int,Whatever)。所以返回类型不是真正的Int"在这种情况下,但你的化妆类型。