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

How to create custom assignment operator in Scala

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

为了使其更友好 class,我想要自定义赋值运算符等,例如我希望所有工作都具有以下内容:

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

任何帮助将不胜感激...之前没有构建过这样的自定义类型,所以覆盖赋值和隐式转换对我来说是新的...

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