如何在Scala中创建自定义赋值运算符

时间:2015-05-15 02:33:57

标签: scala constructor assignment-operator

我尝试创建一个行为类似于Int的自定义数据类型,但具有某些特定的行为和类型(例如,它必须是正面的,它必须符合我们数据库的范围&#39 ; s'整数'类型等。)

为了使它成为一个友好的类,我想拥有自定义赋值运算符等,例如我喜欢以下所有工作:

val g: GPID = 1   // create a GPID type with value 1
val g: GPID = 1L  // take assignment from a Long (and downcast into Int)
if (g == 1) ...   // test the value of GPID type against an Int(1)

这是我到目前为止所做的,但我没有得到预期的行为:

case class GPID(value: Int) extends MappedTo[Int] {
    require(value >= 1, "GPID must be a positive number")
    require(value <= GPDataTypes.integer._2, s"GPID upper bound is ${GPDataTypes.integer._2}")

    def this(l: Long) = this(l.toInt)

    def GPID = value
    def GPID_=(i: Int) = new GPID(i)
    def GPID_=(l: Long) = new GPID(l.toInt)

    override def toString: String = value.toString

    override def hashCode:Int = value

    override def equals(that: Any): Boolean =
        that match {
            case that: Int => this.hashCode == that.hashCode
            case that: Long => this.hashCode == that.hashCode
            case _ => false
        }
}

object GPID {
    implicit val writesGPID = new Writes[GPID] {
        def writes(g: GPID): JsValue = {
            Json.obj(
                "GPID" -> g.value
            )
        }
    }

    implicit val reads: Reads[GPID] = (
        (__ \ "GPID").read[GPID]
        )

    def apply(l: Long) = new GPID(l.toInt)

    implicit def gpid2int(g: GPID): Int = hashCode

    implicit def gpid2long(g: GPID): Long = hashCode.toLong
}

我遇到的问题是:

  1. 作业不起作用,例如: val g: GPID = 1

  2. 隐式转换不起作用,例如: val i: Int = g

  3. 任何帮助都会受到赞赏......没有像这样构建一个自定义类型,所以重写分配和隐式转换对我来说是新的......

1 个答案:

答案 0 :(得分:2)

object TestInt extends App {

  class GPID(val value: Int) {
    require(value >= 1, "GPID must be a positive number")
    require(value <= 10, s"GPID upper bound is 10")

    override def equals(that: Any) = value.equals(that)

    override def toString = value.toString

    // add more methods here (pimp my library)
  }

  implicit def fromInt(value: Int) = new GPID(value)

  implicit def fromInt(value: Long) = new GPID(value.toInt) //possible loss of precision

  val g: GPID = 1
  val g2: GPID = 1L

  if (g == 1)
    println("ONE: " + g)
  else
    println("NOT ONE: " + g)
}

打印:

ONE: 1