2010-12-20 18 views
4

什麼是最好的表達方式,例如,Int字段或參數不應該是負面的?在Scala中表示約束值的最佳方法?

首先想到的是類型上的註釋,如case class Foo(x: Int @NotNegative)。但是我不得不發明自己的註釋,並且不會有任何編譯時檢查或任何其他事情。

有沒有更好的方法?

+0

看到在斯卡拉論壇還這個線程:http://www.scala-lang.org/node/6958 – 2010-12-21 18:09:25

+0

這最近的一篇文章:HTTP:// WWW .springerlink.com/content/978-3-642-16611-2 /#section = 815757&page = 1 – 2010-12-21 18:14:30

回答

4

爲什麼不使用單獨的數據類型?

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)) 
} 

用法:

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

稍好(?),也許,但仍然沒有編譯器檢查:require(x >= 0)

1

目前Scala不支持契約和不變量。

+1

這應該有所澄清。對語言中的契約/不變式沒有直接的支持(例如,作爲方法簽名的一部分的前/後條件),但是對標準庫中的運行時檢查有一些支持。 'require'及其親屬用於指定前提條件,''ensure''可用於指定後置條件。正如@Landei所表明的那樣,類型系統也可以用來指定合約。 – 2010-12-21 18:07:04

+1

@Aaron我已經學會了契約和不變式是編譯時斷言。運行時間檢查很容易以任何語言實現。至於使用類型系統,它可以在一定程度上使用,但在涉及契約和不變量的地方很麻煩和不方便。 – 2010-12-21 21:45:19

+2

其實,「契約」一詞來自埃菲爾,它只是動態強制執行它們。不變量通常也是動態強制執行的。它們很容易在任何(非全部)語言中實現,但艾菲爾爲它們提供了特殊的語法糖。 – 2010-12-23 21:46:41