validations in value classes

前端 未结 3 1027
孤独总比滥情好
孤独总比滥情好 2021-01-06 23:09

SIP-15 implies one can use value classes to define for example new numeric classes, such as positive numbers. Is it possible to code such a constraint that the underlying >

3条回答
  •  一向
    一向 (楼主)
    2021-01-06 23:28

    An implicit conversion to a type marked as having passed your runtime requirement.

    scala> trait Pos
    defined trait Pos
    
    scala> implicit class P(val i: Int with Pos) extends AnyVal { def f = i }
    defined class P
    
    scala> implicit def cv(i: Int): Int with Pos = { require(i>0); i.asInstanceOf[Int with Pos] }
    warning: there was one feature warning; re-run with -feature for details
    cv: (i: Int)Int with Pos
    
    scala> new P(42).f
    res0: Int with Pos = 42
    
    scala> :javap -prv -
            17: invokevirtual #35                 // Method $line5/$read$$iw$$iw$.cv:(I)I
            20: invokevirtual #38                 // Method $line4/$read$$iw$$iw$P$.f$extension:(I)I
    
    scala> new P(-42).f
    java.lang.IllegalArgumentException: requirement failed
      at scala.Predef$.require(Predef.scala:207)
      at .cv(:13)
      ... 33 elided
    

    You can also have private methods that enforce invariants.

    scala> implicit class P(val i: Int with Pos) extends AnyVal { private def g = require(i>0) ; def f = { g; i } }
    defined class P
    
    scala> new P(-42.asInstanceOf[Int with Pos]).f
    java.lang.IllegalArgumentException: requirement failed
      at scala.Predef$.require(Predef.scala:207)
      at P$.$line10$$read$P$$g$extension(:14)
      at P$.f$extension()
      ... 33 elided
    

提交回复
热议问题