¿Cuál es la mejor manera de expresar que, digamos, un Int
campo o parámetro nunca debe ser negativo?
Lo primero que viene a la mente es una anotación sobre el tipo, como case class Foo(x: Int @NotNegative)
. Pero tendría que inventar mi propia anotación, y no habría ningún tipo de verificación en tiempo de compilación ni nada.
¿Hay alguna manera mejor?
Respuestas
4 para la respuesta № 1¿Por qué no usar un tipo de datos separado?
class Natural private (val value: Int) {
require(value >= 0)
def +(that:Natural) = new Natural(this.value + that.value)
def *(that:Natural) = new Natural(this.value * that.value)
def %(that:Natural) = new Natural(this.value % that.value)
def |-|(that:Natural) = Natural.abs(this.value - that.value) //absolute difference
override def toString = value.toString
}
object Natural {
implicit def nat2int(n:Natural) = n.value
def abs(n:Int) = new Natural(math.abs(n))
}
Uso:
val a = Natural.abs(4711)
val b = Natural.abs(-42)
val c = a + b
val d = b - a // works due to implicit conversion, but d is typed as Int
println(a < b) //works due implicit conversion
1 para la respuesta № 2
Ligeramente mejor (?), Tal vez, pero aún no hay verificación del compilador: require(x >= 0)
.
1 para la respuesta № 3
Los contratos e invariantes no son compatibles con Scala en este momento.